1 package org.orekit.estimation.sequential;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.hipparchus.linear.MatrixUtils;
7 import org.hipparchus.linear.RealMatrix;
8 import org.hipparchus.linear.RealVector;
9 import org.junit.Assert;
10 import org.junit.Before;
11 import org.junit.Test;
12 import org.orekit.estimation.DSSTContext;
13 import org.orekit.estimation.DSSTEstimationTestUtils;
14 import org.orekit.estimation.DSSTForce;
15 import org.orekit.estimation.measurements.GroundStation;
16 import org.orekit.estimation.measurements.ObservableSatellite;
17 import org.orekit.estimation.measurements.Range;
18 import org.orekit.estimation.measurements.modifiers.Bias;
19 import org.orekit.forces.radiation.RadiationSensitive;
20 import org.orekit.orbits.Orbit;
21 import org.orekit.orbits.OrbitType;
22 import org.orekit.orbits.PositionAngle;
23 import org.orekit.propagation.PropagationType;
24 import org.orekit.propagation.SpacecraftState;
25 import org.orekit.propagation.conversion.DSSTPropagatorBuilder;
26 import org.orekit.time.AbsoluteDate;
27 import org.orekit.utils.ParameterDriver;
28 import org.orekit.utils.ParameterDriversList;
29
30 public class SemiAnalyticalKalmanModelTest {
31
32
33 private final OrbitType orbitType = OrbitType.EQUINOCTIAL;
34
35
36 private final PositionAngle positionAngle = PositionAngle.MEAN;
37
38
39 private Orbit orbit0;
40
41
42 private DSSTPropagatorBuilder propagatorBuilder;
43
44
45 private CovarianceMatrixProvider covMatrixProvider;
46
47
48 private ParameterDriversList estimatedMeasurementsParameters;
49
50
51 private SemiAnalyticalKalmanEstimator kalman;
52
53
54 private ModelLogger modelLogger;
55
56
57 private int M;
58
59
60 private Range range;
61
62
63 private ParameterDriver satRangeBiasDriver;
64
65
66 private ParameterDriver srpCoefDriver;
67
68
69 private final double tol = 1e-16;
70
71 @Before
72 public void setup() {
73
74
75 DSSTContext context = DSSTEstimationTestUtils.eccentricContext("regular-data:potential:tides");
76
77
78 this.orbit0 = context.initialOrbit;
79 ObservableSatellite sat = new ObservableSatellite(0);
80
81
82 this.propagatorBuilder = context.createBuilder(PropagationType.MEAN, PropagationType.OSCULATING, true,
83 1.0e-6, 60.0, 10., DSSTForce.SOLAR_RADIATION_PRESSURE);
84
85
86 final AbsoluteDate date0 = context.initialOrbit.getDate();
87
88
89 final AbsoluteDate date = date0.shiftedBy(10.);
90 final GroundStation station = context.stations.get(0);
91 this.range = new Range(station, true, date, 18616150., 10., 1., sat);
92
93
94
95 final Bias<Range> satRangeBias = new Bias<Range>(new String[] {"sat range bias"},
96 new double[] {100.},
97 new double[] {10.},
98 new double[] {0.},
99 new double[] {100.});
100 this.satRangeBiasDriver = satRangeBias.getParametersDrivers().get(0);
101 satRangeBiasDriver.setSelected(true);
102 satRangeBiasDriver.setReferenceDate(date);
103 range.addModifier(satRangeBias);
104 for (ParameterDriver driver : range.getParametersDrivers()) {
105 driver.setReferenceDate(date);
106 }
107
108
109 this.estimatedMeasurementsParameters = new ParameterDriversList();
110 for (final ParameterDriver driver : range.getParametersDrivers()) {
111 if (driver.isSelected()) {
112 estimatedMeasurementsParameters.add(driver);
113 }
114 }
115
116 this.srpCoefDriver = propagatorBuilder.getPropagationParametersDrivers().
117 findByName(RadiationSensitive.REFLECTION_COEFFICIENT);
118 srpCoefDriver.setReferenceDate(date);
119 srpCoefDriver.setSelected(true);
120
121
122 final double[] scales = getParametersScale(propagatorBuilder, estimatedMeasurementsParameters);
123 this.M = scales.length;
124 this.covMatrixProvider = setInitialCovarianceMatrix(scales);
125
126
127 final SemiAnalyticalKalmanEstimatorBuilder kalmanBuilder = new SemiAnalyticalKalmanEstimatorBuilder();
128 kalmanBuilder.addPropagationConfiguration(propagatorBuilder, covMatrixProvider);
129 kalmanBuilder.estimatedMeasurementsParameters(estimatedMeasurementsParameters, null);
130 this.kalman = kalmanBuilder.build();
131 this.modelLogger = new ModelLogger();
132 kalman.setObserver(modelLogger);
133 }
134
135 @Test
136 public void ModelPhysicalOutputsTest() {
137
138
139
140 checkModelAtT0();
141
142 }
143
144
145 private void checkModelAtT0() {
146
147
148 final SemiAnalyticalKalmanModel model = new SemiAnalyticalKalmanModel(propagatorBuilder,
149 covMatrixProvider,
150 estimatedMeasurementsParameters,
151 null);
152
153
154
155
156
157 Assert.assertEquals(0., model.getEstimate().getTime(), 0.);
158 Assert.assertEquals(0., model.getCurrentDate().durationFrom(orbit0.getDate()), 0.);
159
160
161 Assert.assertEquals(0, model.getCurrentMeasurementNumber());
162
163
164 final RealVector stateN = model.getEstimate().getState();
165 Assert.assertArrayEquals(new double[M], stateN.toArray(), tol);
166
167
168 final RealVector x = model.getPhysicalEstimatedState();
169 final RealVector expX = MatrixUtils.createRealVector(M);
170 final double[] orbitState0 = new double[6];
171 orbitType.mapOrbitToArray(orbit0, positionAngle, orbitState0, null);
172 expX.setSubVector(0, MatrixUtils.createRealVector(orbitState0));
173 expX.setEntry(6, srpCoefDriver.getReferenceValue());
174 expX.setEntry(7, satRangeBiasDriver.getReferenceValue());
175 final double[] dX = x.subtract(expX).toArray();
176 Assert.assertArrayEquals(new double[M], dX, tol);
177
178
179 final double[][] Pn = model.getEstimate().getCovariance().getData();
180 final double[][] expPn = new double[M][M];
181 for (int i = 0; i < M; i++) {
182 for (int j = 0; j < M; j++) {
183 expPn[i][j] = 1.;
184 }
185 Assert.assertArrayEquals("Failed on line " + i, expPn[i], Pn[i], tol);
186 }
187
188
189 final RealMatrix P = model.getPhysicalEstimatedCovarianceMatrix();
190 final RealMatrix expP = covMatrixProvider.getInitialCovarianceMatrix(new SpacecraftState(orbit0));
191 final double[][] dP = P.subtract(expP).getData();
192 for (int i = 0; i < M; i++) {
193 Assert.assertArrayEquals("Failed on line " + i, new double[M], dP[i], tol);
194 }
195
196
197 Assert.assertNull(model.getEstimate().getInnovationCovariance());
198 Assert.assertNull(model.getPhysicalInnovationCovarianceMatrix());
199 Assert.assertNull(model.getEstimate().getKalmanGain());
200 Assert.assertNull(model.getPhysicalKalmanGain());
201 Assert.assertNull(model.getEstimate().getMeasurementJacobian());
202 Assert.assertNull(model.getPhysicalMeasurementJacobian());
203 Assert.assertNull(model.getEstimate().getStateTransitionMatrix());
204 Assert.assertNull(model.getPhysicalStateTransitionMatrix());
205 }
206
207
208
209
210
211
212 private double[] getParametersScale(final DSSTPropagatorBuilder builder,
213 final ParameterDriversList estimatedMeasurementsParameters) {
214 final List<Double> scaleList = new ArrayList<>();
215
216
217 for (ParameterDriver driver : builder.getOrbitalParametersDrivers().getDrivers()) {
218 if (driver.isSelected()) {
219 scaleList.add(driver.getScale());
220 }
221 }
222
223
224 for (ParameterDriver driver : builder.getPropagationParametersDrivers().getDrivers()) {
225 if (driver.isSelected()) {
226 scaleList.add(driver.getScale());
227 }
228 }
229
230
231 for (ParameterDriver driver : estimatedMeasurementsParameters.getDrivers()) {
232 if (driver.isSelected()) {
233 scaleList.add(driver.getScale());
234 }
235 }
236
237 final double[] scales = new double[scaleList.size()];
238 for (int i = 0; i < scaleList.size(); i++) {
239 scales[i] = scaleList.get(i);
240 }
241 return scales;
242 }
243
244
245
246
247
248
249
250 private CovarianceMatrixProvider setInitialCovarianceMatrix(final double[] scales) {
251
252 final int n = scales.length;
253 final RealMatrix cov = MatrixUtils.createRealMatrix(n, n);
254 for (int i = 0; i < n; i++) {
255 for (int j = 0; j < n; j++) {
256 cov.setEntry(i, j, scales[i] * scales[j]);
257 }
258 }
259 return new ConstantProcessNoise(cov);
260 }
261
262
263
264 public class ModelLogger implements KalmanObserver {
265 KalmanEstimation estimation;
266
267 @Override
268 public void evaluationPerformed(KalmanEstimation estimation) {
269 this.estimation = estimation;
270 }
271 }
272
273 }