1   /* Copyright 2002-2022 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.propagation.sampling;
18  
19  import org.hipparchus.ode.events.Action;
20  import org.junit.After;
21  import org.junit.Assert;
22  import org.junit.Before;
23  import org.junit.Test;
24  import org.orekit.Utils;
25  import org.orekit.frames.FramesFactory;
26  import org.orekit.orbits.KeplerianOrbit;
27  import org.orekit.orbits.Orbit;
28  import org.orekit.orbits.PositionAngle;
29  import org.orekit.propagation.Propagator;
30  import org.orekit.propagation.SpacecraftState;
31  import org.orekit.propagation.analytical.KeplerianPropagator;
32  import org.orekit.propagation.events.DateDetector;
33  import org.orekit.time.AbsoluteDate;
34  import org.orekit.time.TimeScalesFactory;
35  import org.orekit.utils.Constants;
36  
37  public class StepHandlerMultiplexerTest {
38  
39      AbsoluteDate initDate;
40      Propagator propagator;
41  
42      @Before
43      public void setUp() {
44          Utils.setDataRoot("regular-data");
45          initDate = new AbsoluteDate(2020, 2, 28, 16, 15, 0.0, TimeScalesFactory.getUTC());
46          Orbit ic = new KeplerianOrbit(6378137 + 500e3, 1e-3, 0, 0, 0, 0,
47                                        PositionAngle.TRUE, FramesFactory.getGCRF(), initDate, Constants.WGS84_EARTH_MU);
48          propagator = new KeplerianPropagator(ic);
49      }
50  
51      @After
52      public void tearDown() {
53          initDate   = null;
54          propagator = null;
55      }
56  
57      @Test
58      public void testMixedSteps() {
59  
60          StepHandlerMultiplexer multiplexer = propagator.getMultiplexer();
61  
62          InitCheckerHandler initHandler = new InitCheckerHandler(1.0);
63          FixedCounter    counter60  = new FixedCounter();
64          VariableCounter counterVar = new VariableCounter();
65          FixedCounter    counter10  = new FixedCounter();
66  
67          multiplexer.add(60, initHandler);
68          multiplexer.add(60, counter60);
69          multiplexer.add(counterVar);
70          multiplexer.add(10, counter10);
71          Assert.assertEquals(4, multiplexer.getHandlers().size());
72  
73          Assert.assertFalse(initHandler.isInitialized());
74          Assert.assertEquals(1.0, initHandler.getExpected(), Double.MIN_VALUE);
75  
76          propagator.propagate(initDate.shiftedBy(90.0));
77  
78          // verify
79          Assert.assertTrue(initHandler.isInitialized());
80          Assert.assertEquals(2.0, initHandler.getExpected(), Double.MIN_VALUE);
81  
82          Assert.assertEquals( 1,  counter60.initCount);
83          Assert.assertEquals( 2,  counter60.handleCount);
84          Assert.assertEquals( 1,  counter60.finishCount);
85  
86          Assert.assertEquals( 1,  counterVar.initCount);
87          Assert.assertEquals( 1,  counterVar.handleCount);
88          Assert.assertEquals( 1,  counterVar.finishCount);
89  
90          Assert.assertEquals( 1,  counter10.initCount);
91          Assert.assertEquals(10,  counter10.handleCount);
92          Assert.assertEquals( 1,  counter10.finishCount);
93  
94      }
95  
96      @Test
97      public void testRemove() {
98  
99          StepHandlerMultiplexer multiplexer = propagator.getMultiplexer();
100 
101         FixedCounter    counter60  = new FixedCounter();
102         VariableCounter counterVar = new VariableCounter();
103         FixedCounter    counter10  = new FixedCounter();
104 
105         multiplexer.add(60, counter60);
106         multiplexer.add(counterVar);
107         multiplexer.add(10, counter10);
108         Assert.assertEquals(3, multiplexer.getHandlers().size());
109         Assert.assertTrue(((OrekitStepNormalizer) multiplexer.getHandlers().get(0)).getFixedStepHandler() instanceof FixedCounter);
110         Assert.assertEquals(60.0, ((OrekitStepNormalizer) multiplexer.getHandlers().get(0)).getFixedTimeStep(), 1.0e-15);
111         Assert.assertTrue(((OrekitStepNormalizer) multiplexer.getHandlers().get(2)).getFixedStepHandler() instanceof FixedCounter);
112         Assert.assertEquals(10.0, ((OrekitStepNormalizer) multiplexer.getHandlers().get(2)).getFixedTimeStep(), 1.0e-15);
113 
114         // first run with all handlers
115         propagator.propagate(initDate.shiftedBy(90.0));
116         Assert.assertEquals( 1,    counter60.initCount);
117         Assert.assertEquals( 2,    counter60.handleCount);
118         Assert.assertEquals( 1,    counter60.finishCount);
119         Assert.assertEquals(  0.0, counter60.start, 1.0e-15);
120         Assert.assertEquals( 90.0, counter60.stop, 1.0e-15);
121         Assert.assertEquals( 1,    counterVar.initCount);
122         Assert.assertEquals( 1,    counterVar.handleCount);
123         Assert.assertEquals( 1,    counterVar.finishCount);
124         Assert.assertEquals(  0.0, counterVar.start, 1.0e-15);
125         Assert.assertEquals( 90.0, counterVar.stop, 1.0e-15);
126         Assert.assertEquals( 1,    counter10.initCount);
127         Assert.assertEquals(10,    counter10.handleCount);
128         Assert.assertEquals( 1,    counter10.finishCount);
129         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
130         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
131 
132         // removing the handler at 10 seconds
133         multiplexer.remove(counter10);
134         Assert.assertEquals(2, multiplexer.getHandlers().size());
135         propagator.propagate(initDate.shiftedBy(100.0), initDate.shiftedBy(190.0));
136         Assert.assertEquals( 2,    counter60.initCount);
137         Assert.assertEquals( 4,    counter60.handleCount);
138         Assert.assertEquals( 2,    counter60.initCount);
139         Assert.assertEquals(100.0, counter60.start, 1.0e-15);
140         Assert.assertEquals(190.0, counter60.stop, 1.0e-15);
141         Assert.assertEquals( 2,    counterVar.initCount);
142         Assert.assertEquals( 2,    counterVar.handleCount);
143         Assert.assertEquals( 2,    counterVar.finishCount);
144         Assert.assertEquals(100.0, counterVar.start, 1.0e-15);
145         Assert.assertEquals(190.0, counterVar.stop, 1.0e-15);
146         Assert.assertEquals( 1,    counter10.initCount);
147         Assert.assertEquals(10,    counter10.handleCount);
148         Assert.assertEquals( 1,    counter10.initCount);
149         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
150         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
151 
152         // attempting to remove a handler already removed
153         multiplexer.remove(counter10);
154         Assert.assertEquals(2, multiplexer.getHandlers().size());
155         propagator.propagate(initDate.shiftedBy(200.0), initDate.shiftedBy(290.0));
156         Assert.assertEquals( 3,    counter60.initCount);
157         Assert.assertEquals( 6,    counter60.handleCount);
158         Assert.assertEquals( 3,    counter60.finishCount);
159         Assert.assertEquals(200.0, counter60.start, 1.0e-15);
160         Assert.assertEquals(290.0, counter60.stop, 1.0e-15);
161         Assert.assertEquals( 3,    counterVar.initCount);
162         Assert.assertEquals( 3,    counterVar.handleCount);
163         Assert.assertEquals( 3,    counterVar.finishCount);
164         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
165         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
166         Assert.assertEquals( 1,    counter10.initCount);
167         Assert.assertEquals(10,    counter10.handleCount);
168         Assert.assertEquals( 1,    counter10.finishCount);
169         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
170         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
171         
172         // removing the handler with variable stepsize
173         multiplexer.remove(counterVar);
174         Assert.assertEquals(1, multiplexer.getHandlers().size());
175         propagator.propagate(initDate.shiftedBy(300.0), initDate.shiftedBy(390.0));
176         Assert.assertEquals( 4,    counter60.initCount);
177         Assert.assertEquals( 8,    counter60.handleCount);
178         Assert.assertEquals( 4,    counter60.initCount);
179         Assert.assertEquals(300.0, counter60.start, 1.0e-15);
180         Assert.assertEquals(390.0, counter60.stop, 1.0e-15);
181         Assert.assertEquals( 3,    counterVar.initCount);
182         Assert.assertEquals( 3,    counterVar.handleCount);
183         Assert.assertEquals( 3,    counterVar.finishCount);
184         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
185         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
186         Assert.assertEquals( 1,    counter10.initCount);
187         Assert.assertEquals(10,    counter10.handleCount);
188         Assert.assertEquals( 1,    counter10.initCount);
189         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
190         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
191 
192         // attempting to remove a handler already removed
193         multiplexer.remove(counterVar);
194         Assert.assertEquals(1, multiplexer.getHandlers().size());
195         propagator.propagate(initDate.shiftedBy(400.0), initDate.shiftedBy(490.0));
196         Assert.assertEquals( 5,    counter60.initCount);
197         Assert.assertEquals(10,    counter60.handleCount);
198         Assert.assertEquals( 5,    counter60.finishCount);
199         Assert.assertEquals(400.0, counter60.start, 1.0e-15);
200         Assert.assertEquals(490.0, counter60.stop, 1.0e-15);
201         Assert.assertEquals( 3,    counterVar.initCount);
202         Assert.assertEquals( 3,    counterVar.handleCount);
203         Assert.assertEquals( 3,    counterVar.finishCount);
204         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
205         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
206         Assert.assertEquals( 1,    counter10.initCount);
207         Assert.assertEquals(10,    counter10.handleCount);
208         Assert.assertEquals( 1,    counter10.finishCount);
209         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
210         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
211         
212         // removing everything
213         multiplexer.clear();
214         Assert.assertEquals(0, multiplexer.getHandlers().size());
215         propagator.propagate(initDate.shiftedBy(500.0), initDate.shiftedBy(590.0));
216         Assert.assertEquals( 5,    counter60.initCount);
217         Assert.assertEquals(10,    counter60.handleCount);
218         Assert.assertEquals( 5,    counter60.finishCount);
219         Assert.assertEquals(400.0, counter60.start, 1.0e-15);
220         Assert.assertEquals(490.0, counter60.stop, 1.0e-15);
221         Assert.assertEquals( 3,    counterVar.initCount);
222         Assert.assertEquals( 3,    counterVar.handleCount);
223         Assert.assertEquals( 3,    counterVar.finishCount);
224         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
225         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
226         Assert.assertEquals( 1,    counter10.initCount);
227         Assert.assertEquals(10,    counter10.handleCount);
228         Assert.assertEquals( 1,    counter10.finishCount);
229         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
230         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
231         
232     }
233 
234     @Test
235     public void testOnTheFlyChanges() {
236 
237         StepHandlerMultiplexer multiplexer = propagator.getMultiplexer();
238 
239         double          add60      =  3.0;
240         double          rem60      = 78.0;
241         FixedCounter    counter60  = new FixedCounter();
242         propagator.addEventDetector(new DateDetector(initDate.shiftedBy(add60)).
243                                     withHandler((s, d, i) -> {
244                                         multiplexer.add(60.0, counter60);
245                                         return Action.CONTINUE;
246                                     }));
247         propagator.addEventDetector(new DateDetector(initDate.shiftedBy(rem60)).
248                                     withHandler((s, d, i) -> {
249                                         multiplexer.remove(counter60);
250                                         return Action.CONTINUE;
251                                     }));
252 
253         double          addVar     =  5.0;
254         double          remVar     =  7.0;
255         VariableCounter counterVar = new VariableCounter();
256         propagator.addEventDetector(new DateDetector(initDate.shiftedBy(addVar)).
257                                     withHandler((s, d, i) -> {
258                                         multiplexer.add(counterVar);
259                                         return Action.CONTINUE;
260                                     }));
261         propagator.addEventDetector(new DateDetector(initDate.shiftedBy(remVar)).
262                                     withHandler((s, d, i) -> {
263                                         multiplexer.remove(counterVar);
264                                         return Action.CONTINUE;
265                                     }));
266 
267         double          add10      =  6.0;
268         double          rem10      = 82.0;
269         FixedCounter    counter10  = new FixedCounter();
270         propagator.addEventDetector(new DateDetector(initDate.shiftedBy(add10)).
271                                     withHandler((s, d, i) -> {
272                                         multiplexer.add(10.0, counter10);
273                                         return Action.CONTINUE;
274                                     }));
275         propagator.addEventDetector(new DateDetector(initDate.shiftedBy(rem10)).
276                                     withHandler((s, d, i) -> {
277                                         multiplexer.clear();
278                                         return Action.CONTINUE;
279                                     }));
280 
281         // full run, which will add and remove step handlers on the fly
282         propagator.propagate(initDate.shiftedBy(90.0));
283         Assert.assertEquals( 1,     counter60.initCount);
284         Assert.assertEquals( 2,     counter60.handleCount);
285         Assert.assertEquals( 1,     counter60.finishCount);
286         Assert.assertEquals(add60,  counter60.start, 1.0e-15);
287         Assert.assertEquals(rem60,  counter60.stop, 1.0e-15);
288         Assert.assertEquals( 1,     counterVar.initCount);
289         Assert.assertEquals( 2,     counterVar.handleCount); // event at add10 splits the variable step in two parts
290         Assert.assertEquals( 1,     counterVar.finishCount);
291         Assert.assertEquals(addVar, counterVar.start, 1.0e-15);
292         Assert.assertEquals(remVar, counterVar.stop, 1.0e-15);
293         Assert.assertEquals( 1,     counter10.initCount);
294         Assert.assertEquals( 8,     counter10.handleCount);
295         Assert.assertEquals( 1,     counter10.finishCount);
296         Assert.assertEquals(add10,  counter10.start, 1.0e-15);
297         Assert.assertEquals(rem10,  counter10.stop, 1.0e-15);
298 
299     }
300 
301     private class InitCheckerHandler implements OrekitFixedStepHandler {
302 
303         private double expected;
304         private boolean initialized;
305 
306         public InitCheckerHandler(final double expected) {
307             this.expected    = expected;
308             this.initialized = false;
309         }
310 
311         @Override
312         public void init(SpacecraftState s0, AbsoluteDate t, double step) {
313             initialized = true;
314         }
315 
316         @Override
317         public void handleStep(SpacecraftState currentState) {
318             this.expected = 2.0;
319         }
320 
321         boolean isInitialized() {
322             return initialized;
323         }
324 
325         double getExpected() {
326             return expected;
327         }
328 
329     }
330 
331     private class FixedCounter implements OrekitFixedStepHandler {
332 
333         private int    initCount;
334         private int    handleCount;
335         private int    finishCount;
336         private double start;
337         private double stop;
338 
339         @Override
340         public void init(SpacecraftState s0, AbsoluteDate t, double step) {
341             ++initCount;
342             start = s0.getDate().durationFrom(initDate);
343         }
344 
345         @Override
346         public void handleStep(SpacecraftState currentState) {
347             ++handleCount;
348         }
349 
350         @Override
351         public void finish(SpacecraftState finalState) {
352             ++finishCount;
353             stop = finalState.getDate().durationFrom(initDate);
354         }
355 
356     }
357 
358     private class VariableCounter implements OrekitStepHandler {
359 
360         private int    initCount;
361         private int    handleCount;
362         private int    finishCount;
363         private double start;
364         private double stop;
365 
366         @Override
367         public void init(SpacecraftState s0, AbsoluteDate t) {
368             ++initCount;
369             start = s0.getDate().durationFrom(initDate);
370         }
371 
372         @Override
373         public void handleStep(OrekitStepInterpolator interpolator) {
374             ++handleCount;
375         }
376 
377         @Override
378         public void finish(SpacecraftState finalState) {
379             ++finishCount;
380             stop = finalState.getDate().durationFrom(initDate);
381         }
382 
383     }
384 
385 }