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