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.analytical;
18  
19  import java.util.Arrays;
20  import java.util.Collections;
21  
22  import org.hamcrest.CoreMatchers;
23  import org.hamcrest.MatcherAssert;
24  import org.junit.Assert;
25  import org.junit.Before;
26  import org.junit.Test;
27  import org.orekit.OrekitMatchers;
28  import org.orekit.Utils;
29  import org.orekit.errors.OrekitException;
30  import org.orekit.frames.Frame;
31  import org.orekit.frames.FramesFactory;
32  import org.orekit.orbits.KeplerianOrbit;
33  import org.orekit.orbits.PositionAngle;
34  import org.orekit.propagation.BoundedPropagator;
35  import org.orekit.propagation.EphemerisGenerator;
36  import org.orekit.propagation.SpacecraftState;
37  import org.orekit.time.AbsoluteDate;
38  import org.orekit.utils.Constants;
39  
40  /**
41   * Tests for {@link AggregateBoundedPropagator}.
42   *
43   * @author Evan Ward
44   */
45  public class AggregateBoundedPropagatorTest {
46  
47      public static final Frame frame = FramesFactory.getGCRF();
48  
49      /** Set Orekit data. */
50      @Before
51      public void setUp() {
52          Utils.setDataRoot("regular-data");
53      }
54  
55      /**
56       * Check {@link AggregateBoundedPropagator#propagateOrbit(AbsoluteDate)} when the
57       * constituent propagators are exactly adjacent.
58       *
59       * @throws Exception on error.
60       */
61      @Test
62      public void testAdjacent() throws Exception {
63          // setup
64          AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
65          BoundedPropagator p1 = createPropagator(date, date.shiftedBy(10), 0);
66          BoundedPropagator p2 = createPropagator(date.shiftedBy(10), date.shiftedBy(20), 1);
67  
68          // action
69          BoundedPropagator actual = new AggregateBoundedPropagator(Arrays.asList(p1, p2));
70  
71          //verify
72          int ulps = 0;
73          MatcherAssert.assertThat(actual.getFrame(), CoreMatchers.is(p1.getFrame()));
74          MatcherAssert.assertThat(actual.getMinDate(), CoreMatchers.is(date));
75          MatcherAssert.assertThat(actual.getMaxDate(), CoreMatchers.is(date.shiftedBy(20)));
76          MatcherAssert.assertThat(
77                  actual.propagate(date).getPVCoordinates(),
78                  OrekitMatchers.pvCloseTo(p1.propagate(date).getPVCoordinates(), ulps));
79          MatcherAssert.assertThat(
80                  actual.propagate(date.shiftedBy(5)).getPVCoordinates(),
81                  OrekitMatchers.pvCloseTo(p1.propagate(date.shiftedBy(5)).getPVCoordinates(), ulps));
82          MatcherAssert.assertThat(
83                  actual.propagate(date.shiftedBy(10)).getPVCoordinates(),
84                  OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(10)).getPVCoordinates(), ulps));
85          MatcherAssert.assertThat(
86                  actual.propagate(date.shiftedBy(15)).getPVCoordinates(),
87                  OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(15)).getPVCoordinates(), ulps));
88          MatcherAssert.assertThat(
89                  actual.propagate(date.shiftedBy(20)).getPVCoordinates(),
90                  OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(20)).getPVCoordinates(), ulps));
91      }
92  
93      /**
94       * Check {@link AggregateBoundedPropagator#propagateOrbit(AbsoluteDate)} when the
95       * constituent propagators overlap.
96       *
97       * @throws Exception on error.
98       */
99      @Test
100     public void testOverlap() throws Exception {
101         // setup
102         AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
103         BoundedPropagator p1 = createPropagator(date, date.shiftedBy(25), 0);
104         BoundedPropagator p2 = createPropagator(date.shiftedBy(10), date.shiftedBy(20), 1);
105 
106         // action
107         BoundedPropagator actual = new AggregateBoundedPropagator(Arrays.asList(p1, p2));
108 
109         //verify
110         int ulps = 0;
111         MatcherAssert.assertThat(actual.getFrame(), CoreMatchers.is(p1.getFrame()));
112         MatcherAssert.assertThat(actual.getMinDate(), CoreMatchers.is(date));
113         MatcherAssert.assertThat(actual.getMaxDate(), CoreMatchers.is(date.shiftedBy(20)));
114         MatcherAssert.assertThat(
115                 actual.propagate(date).getPVCoordinates(),
116                 OrekitMatchers.pvCloseTo(p1.propagate(date).getPVCoordinates(), ulps));
117         MatcherAssert.assertThat(
118                 actual.propagate(date.shiftedBy(5)).getPVCoordinates(),
119                 OrekitMatchers.pvCloseTo(p1.propagate(date.shiftedBy(5)).getPVCoordinates(), ulps));
120         MatcherAssert.assertThat(
121                 actual.propagate(date.shiftedBy(10)).getPVCoordinates(),
122                 OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(10)).getPVCoordinates(), ulps));
123         MatcherAssert.assertThat(
124                 actual.propagate(date.shiftedBy(15)).getPVCoordinates(),
125                 OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(15)).getPVCoordinates(), ulps));
126         MatcherAssert.assertThat(
127                 actual.propagate(date.shiftedBy(20)).getPVCoordinates(),
128                 OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(20)).getPVCoordinates(), ulps));
129     }
130 
131     /**
132      * Check {@link AggregateBoundedPropagator#propagateOrbit(AbsoluteDate)} with a gap
133      * between the constituent propagators.
134      *
135      * @throws Exception on error.
136      */
137     @Test
138     public void testGap() throws Exception {
139         // setup
140         AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
141         BoundedPropagator p1 = createPropagator(date, date.shiftedBy(1), 0);
142         BoundedPropagator p2 = createPropagator(date.shiftedBy(10), date.shiftedBy(20), 1);
143 
144         // action
145         BoundedPropagator actual = new AggregateBoundedPropagator(Arrays.asList(p1, p2));
146 
147         //verify
148         int ulps = 0;
149         MatcherAssert.assertThat(actual.getFrame(), CoreMatchers.is(p1.getFrame()));
150         MatcherAssert.assertThat(actual.getMinDate(), CoreMatchers.is(date));
151         MatcherAssert.assertThat(actual.getMaxDate(), CoreMatchers.is(date.shiftedBy(20)));
152         MatcherAssert.assertThat(
153                 actual.propagate(date).getPVCoordinates(),
154                 OrekitMatchers.pvCloseTo(p1.propagate(date).getPVCoordinates(), ulps));
155         MatcherAssert.assertThat(
156                 actual.propagate(date.shiftedBy(10)).getPVCoordinates(),
157                 OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(10)).getPVCoordinates(), ulps));
158         MatcherAssert.assertThat(
159                 actual.propagate(date.shiftedBy(15)).getPVCoordinates(),
160                 OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(15)).getPVCoordinates(), ulps));
161         MatcherAssert.assertThat(
162                 actual.propagate(date.shiftedBy(20)).getPVCoordinates(),
163                 OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(20)).getPVCoordinates(), ulps));
164         try {
165             // may or may not throw an exception depending on the type of propagator.
166             MatcherAssert.assertThat(
167                     actual.propagate(date.shiftedBy(5)).getPVCoordinates(),
168                     OrekitMatchers.pvCloseTo(p1.propagate(date.shiftedBy(5)).getPVCoordinates(), ulps));
169         } catch (OrekitException e) {
170             // expected
171         }
172     }
173 
174     @Test
175     public void testOutsideBounds() throws Exception {
176         // setup
177         AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
178         BoundedPropagator p1 = createPropagator(date, date.shiftedBy(10), 0);
179         BoundedPropagator p2 = createPropagator(date.shiftedBy(10), date.shiftedBy(20), 1);
180 
181         // action
182         BoundedPropagator actual = new AggregateBoundedPropagator(Arrays.asList(p1, p2));
183 
184         // verify
185         int ulps = 0;
186         // before bound of first propagator
187         try {
188             // may or may not throw an exception depending on the type of propagator.
189             MatcherAssert.assertThat(
190                     actual.propagate(date.shiftedBy(-60)).getPVCoordinates(),
191                     OrekitMatchers.pvCloseTo(p1.propagate(date.shiftedBy(-60)).getPVCoordinates(), ulps));
192         } catch (OrekitException e) {
193             // expected
194         }
195         try {
196             // may or may not throw an exception depending on the type of propagator.
197             MatcherAssert.assertThat(
198                     actual.getPVCoordinates(date.shiftedBy(-60), frame),
199                     OrekitMatchers.pvCloseTo(p1.propagate(date.shiftedBy(-60)).getPVCoordinates(), ulps));
200         } catch (OrekitException e) {
201             // expected
202         }
203         // after bound of last propagator
204         try {
205             // may or may not throw an exception depending on the type of propagator.
206             MatcherAssert.assertThat(
207                     actual.propagate(date.shiftedBy(60)).getPVCoordinates(),
208                     OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(60)).getPVCoordinates(), ulps));
209         } catch (OrekitException e) {
210             // expected
211         }
212         try {
213             // may or may not throw an exception depending on the type of propagator.
214             MatcherAssert.assertThat(
215                     actual.getPVCoordinates(date.shiftedBy(60), frame),
216                     OrekitMatchers.pvCloseTo(p2.propagate(date.shiftedBy(60)).getPVCoordinates(), ulps));
217         } catch (OrekitException e) {
218             // expected
219         }
220 
221     }
222 
223     /**
224      * Check that resetting the state is prohibited.
225      */
226     @Test
227     public void testResetState() {
228         // setup
229         AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
230         BoundedPropagator p1 = createPropagator(date, date.shiftedBy(10), 0);
231         BoundedPropagator p2 = createPropagator(date.shiftedBy(10), date.shiftedBy(20), 1);
232         SpacecraftState ic = p2.getInitialState();
233 
234         // action
235         BoundedPropagator actual = new AggregateBoundedPropagator(Arrays.asList(p1, p2));
236 
237         // verify
238         try {
239             actual.resetInitialState(ic);
240             Assert.fail("Expected Exception");
241         } catch (OrekitException e) {
242             // expected
243         }
244     }
245 
246     /**
247      * Check that creating an aggregate propagator from an empty list of propagators is
248      * prohibited.
249      */
250     @Test
251     public void testEmptyList() {
252         // action + verify
253         try {
254             new AggregateBoundedPropagator(Collections.emptyList());
255             Assert.fail("Expected Exception");
256         } catch (OrekitException e) {
257             // expected
258         }
259     }
260 
261     /**
262      * Create a propagator with the given dates.
263      *
264      * @param start date.
265      * @param end   date.
266      * @param v     true anomaly.
267      * @return a bound propagator with the given dates.
268      */
269     private BoundedPropagator createPropagator(AbsoluteDate start,
270                                                AbsoluteDate end,
271                                                double v) {
272         double gm = Constants.EGM96_EARTH_MU;
273         KeplerianPropagator propagator = new KeplerianPropagator(new KeplerianOrbit(
274                 6778137, 0, 0, 0, 0, v, PositionAngle.TRUE, frame, start, gm));
275         final EphemerisGenerator generator = propagator.getEphemerisGenerator();
276         propagator.propagate(start, end);
277         return generator.getGeneratedEphemeris();
278     }
279 
280 }