1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements;
18
19 import java.util.List;
20
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.stat.descriptive.StreamingStatistics;
23 import org.hipparchus.stat.descriptive.rank.Median;
24 import org.hipparchus.util.FastMath;
25 import org.junit.Assert;
26 import org.junit.Test;
27 import org.orekit.estimation.Context;
28 import org.orekit.estimation.EstimationTestUtils;
29 import org.orekit.orbits.OrbitType;
30 import org.orekit.orbits.PositionAngle;
31 import org.orekit.propagation.Propagator;
32 import org.orekit.propagation.SpacecraftState;
33 import org.orekit.propagation.conversion.NumericalPropagatorBuilder;
34 import org.orekit.time.AbsoluteDate;
35 import org.orekit.utils.Differentiation;
36 import org.orekit.utils.ParameterDriver;
37 import org.orekit.utils.ParameterFunction;
38 import org.orekit.utils.StateFunction;
39
40 public class AngularRaDecTest {
41
42
43
44
45 @Test
46 public void testBug473OnValues() {
47
48 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
49
50 final NumericalPropagatorBuilder propagatorBuilder =
51 context.createBuilder(OrbitType.EQUINOCTIAL, PositionAngle.TRUE, false,
52 1.0e-6, 60.0, 0.001);
53
54
55 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
56 propagatorBuilder);
57 final List<ObservedMeasurement<?>> measurements =
58 EstimationTestUtils.createMeasurements(propagator,
59 new AngularRaDecMeasurementCreator(context),
60 0.25, 3.0, 600.0);
61
62 propagator.clearStepHandlers();
63
64
65 final StreamingStatistics raDiffStat = new StreamingStatistics();
66 final StreamingStatistics decDiffStat = new StreamingStatistics();
67
68 for (final ObservedMeasurement<?> measurement : measurements) {
69
70
71 final AbsoluteDate datemeas = measurement.getDate();
72 SpacecraftState state = propagator.propagate(datemeas);
73
74
75 final EstimatedMeasurement<?> estimated = measurement.estimate(0, 0, new SpacecraftState[] { state });
76
77
78 raDiffStat.addValue(FastMath.abs(estimated.getEstimatedValue()[0] - measurement.getObservedValue()[0]));
79 decDiffStat.addValue(FastMath.abs(estimated.getEstimatedValue()[1] - measurement.getObservedValue()[1]));
80 }
81
82
83 Assert.assertEquals(0.0, raDiffStat.getMean(), 6.9e-11);
84 Assert.assertEquals(0.0, raDiffStat.getStandardDeviation(), 8.5e-11);
85
86 Assert.assertEquals(0.0, decDiffStat.getMean(), 4.5e-11);
87 Assert.assertEquals(0.0, decDiffStat.getStandardDeviation(), 3e-11);
88 }
89
90
91
92
93 @Test
94 public void testStateDerivatives() {
95
96 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
97
98 final NumericalPropagatorBuilder propagatorBuilder =
99 context.createBuilder(OrbitType.EQUINOCTIAL, PositionAngle.TRUE, false,
100 1.0e-6, 60.0, 0.001);
101
102
103 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
104 propagatorBuilder);
105 final List<ObservedMeasurement<?>> measurements =
106 EstimationTestUtils.createMeasurements(propagator,
107 new AngularRaDecMeasurementCreator(context),
108 0.25, 3.0, 600.0);
109
110 propagator.clearStepHandlers();
111
112
113 double[] RaerrorsP = new double[3 * measurements.size()];
114 double[] RaerrorsV = new double[3 * measurements.size()];
115 double[] DecerrorsP = new double[3 * measurements.size()];
116 double[] DecerrorsV = new double[3 * measurements.size()];
117 int RaindexP = 0;
118 int RaindexV = 0;
119 int DecindexP = 0;
120 int DecindexV = 0;
121
122 for (final ObservedMeasurement<?> measurement : measurements) {
123
124
125 final GroundStation stationParameter = ((AngularRaDec) measurement).getStation();
126
127
128
129
130
131
132
133
134 final AbsoluteDate datemeas = measurement.getDate();
135 SpacecraftState state = propagator.propagate(datemeas);
136 final Vector3D stationP = stationParameter.getOffsetToInertial(state.getFrame(), datemeas).transformPosition(Vector3D.ZERO);
137 final double meanDelay = AbstractMeasurement.signalTimeOfFlight(state.getPVCoordinates(), stationP, datemeas);
138
139 final AbsoluteDate date = measurement.getDate().shiftedBy(-0.75 * meanDelay);
140 state = propagator.propagate(date);
141 final EstimatedMeasurement<?> estimated = measurement.estimate(0, 0, new SpacecraftState[] { state });
142 Assert.assertEquals(2, estimated.getParticipants().length);
143 final double[][] jacobian = estimated.getStateDerivatives(0);
144
145
146 final double[][] finiteDifferencesJacobian =
147 Differentiation.differentiate(new StateFunction() {
148 public double[] value(final SpacecraftState state) {
149 return measurement.estimate(0, 0, new SpacecraftState[] { state }).getEstimatedValue();
150 }
151 }, measurement.getDimension(), propagator.getAttitudeProvider(), OrbitType.CARTESIAN,
152 PositionAngle.TRUE, 250.0, 4).value(state);
153
154 Assert.assertEquals(finiteDifferencesJacobian.length, jacobian.length);
155 Assert.assertEquals(finiteDifferencesJacobian[0].length, jacobian[0].length);
156
157 final double smallest = FastMath.ulp((double) 1.0);
158
159 for (int i = 0; i < jacobian.length; ++i) {
160 for (int j = 0; j < jacobian[i].length; ++j) {
161 double relativeError = FastMath.abs((finiteDifferencesJacobian[i][j] - jacobian[i][j]) /
162 finiteDifferencesJacobian[i][j]);
163
164 if ((FastMath.sqrt(finiteDifferencesJacobian[i][j]) < smallest) && (FastMath.sqrt(jacobian[i][j]) < smallest) ){
165 relativeError = 0.0;
166 }
167
168 if (j < 3) {
169 if (i == 0) {
170 RaerrorsP[RaindexP++] = relativeError;
171 } else {
172 DecerrorsP[DecindexP++] = relativeError;
173 }
174 } else {
175 if (i == 0) {
176 RaerrorsV[RaindexV++] = relativeError;
177 } else {
178 DecerrorsV[DecindexV++] = relativeError;
179 }
180 }
181 }
182 }
183 }
184
185
186 Assert.assertEquals(0.0, new Median().evaluate(RaerrorsP), 4.8e-11);
187 Assert.assertEquals(0.0, new Median().evaluate(RaerrorsV), 2.2e-5);
188
189
190 Assert.assertEquals(0.0, new Median().evaluate(DecerrorsP), 1.5e-11);
191 Assert.assertEquals(0.0, new Median().evaluate(DecerrorsV), 5.4e-6);
192 }
193
194
195
196
197 @Test
198 public void testParameterDerivatives() {
199
200 Context context = EstimationTestUtils.geoStationnaryContext("regular-data:potential:tides");
201
202 final NumericalPropagatorBuilder propagatorBuilder =
203 context.createBuilder(OrbitType.EQUINOCTIAL, PositionAngle.TRUE, false,
204 1.0e-6, 60.0, 0.001);
205
206
207 for (final GroundStation station : context.stations) {
208 station.getClockOffsetDriver().setSelected(true);
209 station.getEastOffsetDriver().setSelected(true);
210 station.getNorthOffsetDriver().setSelected(true);
211 station.getZenithOffsetDriver().setSelected(true);
212 }
213 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
214 propagatorBuilder);
215 final List<ObservedMeasurement<?>> measurements =
216 EstimationTestUtils.createMeasurements(propagator,
217 new AngularRaDecMeasurementCreator(context),
218 0.25, 3.0, 600.0);
219 propagator.clearStepHandlers();
220
221 for (final ObservedMeasurement<?> measurement : measurements) {
222
223
224 final GroundStation stationParameter = ((AngularRaDec) measurement).getStation();
225
226
227
228
229
230
231
232
233 final AbsoluteDate datemeas = measurement.getDate();
234 final SpacecraftState stateini = propagator.propagate(datemeas);
235 final Vector3D stationP = stationParameter.getOffsetToInertial(stateini.getFrame(), datemeas).transformPosition(Vector3D.ZERO);
236 final double meanDelay = AbstractMeasurement.signalTimeOfFlight(stateini.getPVCoordinates(), stationP, datemeas);
237
238 final AbsoluteDate date = measurement.getDate().shiftedBy(-0.75 * meanDelay);
239 final SpacecraftState state = propagator.propagate(date);
240 final ParameterDriver[] drivers = new ParameterDriver[] {
241 stationParameter.getEastOffsetDriver(),
242 stationParameter.getNorthOffsetDriver(),
243 stationParameter.getZenithOffsetDriver()
244 };
245 for (int i = 0; i < 3; ++i) {
246 final double[] gradient = measurement.estimate(0, 0, new SpacecraftState[] { state }).getParameterDerivatives(drivers[i]);
247 Assert.assertEquals(2, measurement.getDimension());
248 Assert.assertEquals(2, gradient.length);
249
250 for (final int k : new int[] {0, 1}) {
251 final ParameterFunction dMkdP =
252 Differentiation.differentiate(new ParameterFunction() {
253
254 @Override
255 public double value(final ParameterDriver parameterDriver) {
256 return measurement.estimate(0, 0, new SpacecraftState[] { state }).getEstimatedValue()[k];
257 }
258 }, 3, 50.0 * drivers[i].getScale());
259 final double ref = dMkdP.value(drivers[i]);
260
261 if (ref > 1.e-12) {
262 Assert.assertEquals(ref, gradient[k], 3e-9 * FastMath.abs(ref));
263 }
264 }
265 }
266 }
267 }
268 }
269