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.estimation.measurements.generation;
18  
19  import java.util.SortedSet;
20  
21  import org.hipparchus.random.RandomGenerator;
22  import org.hipparchus.random.Well19937a;
23  import org.hipparchus.util.FastMath;
24  import org.junit.Assert;
25  import org.junit.Before;
26  import org.orekit.estimation.Context;
27  import org.orekit.estimation.EstimationTestUtils;
28  import org.orekit.estimation.Force;
29  import org.orekit.estimation.measurements.GroundStation;
30  import org.orekit.estimation.measurements.ObservableSatellite;
31  import org.orekit.estimation.measurements.ObservedMeasurement;
32  import org.orekit.orbits.OrbitType;
33  import org.orekit.orbits.PositionAngle;
34  import org.orekit.propagation.Propagator;
35  import org.orekit.propagation.SpacecraftState;
36  import org.orekit.propagation.conversion.NumericalPropagatorBuilder;
37  import org.orekit.propagation.events.ElevationDetector;
38  import org.orekit.propagation.events.handlers.ContinueOnEvent;
39  import org.orekit.time.AbsoluteDate;
40  import org.orekit.time.FixedStepSelector;
41  import org.orekit.time.TimeScalesFactory;
42  
43  public abstract class AbstractGroundMeasurementBuilderTest<T extends ObservedMeasurement<T>> {
44  
45      protected abstract MeasurementBuilder<T> getBuilder(RandomGenerator random,
46                                                          GroundStation groundStation,
47                                                          ObservableSatellite satellite);
48  
49      private Propagator buildPropagator() {
50          return EstimationTestUtils.createPropagator(context.initialOrbit, propagatorBuilder);
51      }
52  
53      protected void doTest(long seed, double startPeriod, double endPeriod, int expectedMeasurements, double tolerance) {
54         Generator generator = new Generator();
55         final double step = 60.0;
56         generator.addPropagator(buildPropagator()); // dummy propagator 1
57         generator.addPropagator(buildPropagator()); // dummy propagator 2
58         final ObservableSatellite satellite = generator.addPropagator(buildPropagator()); // relevant propagator 3
59         generator.addPropagator(buildPropagator()); // dummy propagator 4
60         generator.addScheduler(new EventBasedScheduler<>(getBuilder(new Well19937a(seed), context.stations.get(0), satellite),
61                                                          new FixedStepSelector(step, TimeScalesFactory.getUTC()),
62                                                          generator.getPropagator(satellite),
63                                                          new ElevationDetector(context.stations.get(0).getBaseFrame()).
64                                                          withConstantElevation(FastMath.toRadians(5.0)).
65                                                          withHandler(new ContinueOnEvent<>()),
66                                                          SignSemantic.FEASIBLE_MEASUREMENT_WHEN_POSITIVE));
67         final double period = context.initialOrbit.getKeplerianPeriod();
68         AbsoluteDate t0     = context.initialOrbit.getDate().shiftedBy(startPeriod * period);
69         AbsoluteDate t1     = context.initialOrbit.getDate().shiftedBy(endPeriod   * period);
70         SortedSet<ObservedMeasurement<?>> measurements = generator.generate(t0, t1);
71         Assert.assertEquals(expectedMeasurements, measurements.size());
72         Propagator propagator = buildPropagator();
73         double maxError = 0;
74         AbsoluteDate previous = null;
75         AbsoluteDate tInf = t0.compareTo(t1) < 0 ? t0 : t1;
76         AbsoluteDate tSup = t0.compareTo(t1) < 0 ? t1 : t0;
77         for (ObservedMeasurement<?> measurement : measurements) {
78             AbsoluteDate date = measurement.getDate();
79             double[] m = measurement.getObservedValue();
80             Assert.assertTrue(date.compareTo(tInf) >= 0);
81             Assert.assertTrue(date.compareTo(tSup) <= 0);
82             if (previous != null) {
83                 // measurements are always chronological, even with backward propagation,
84                 // due to the SortedSet (which is intended for combining several
85                 // measurements types with different builders and schedulers)
86                 Assert.assertTrue(date.durationFrom(previous) >= 0.999999 * step);
87             }
88             previous = date;
89             SpacecraftState state = propagator.propagate(date);
90             double[] e = measurement.estimate(0, 0, new SpacecraftState[] { state }).getEstimatedValue();
91             for (int i = 0; i < m.length; ++i) {
92                 maxError = FastMath.max(maxError, FastMath.abs(e[i] - m[i]));
93             }
94         }
95         Assert.assertEquals(0.0, maxError, tolerance);
96      }
97  
98      @Before
99      public void setUp() {
100         context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
101 
102         propagatorBuilder = context.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true,
103                                                   1.0e-6, 300.0, 0.001, Force.POTENTIAL,
104                                                   Force.THIRD_BODY_SUN, Force.THIRD_BODY_MOON);
105     }
106 
107     Context context;
108     NumericalPropagatorBuilder propagatorBuilder;
109 
110 }