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.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29
30 import org.hipparchus.analysis.UnivariateVectorFunction;
31 import org.hipparchus.analysis.differentiation.FiniteDifferencesDifferentiator;
32 import org.hipparchus.analysis.differentiation.Gradient;
33 import org.hipparchus.analysis.differentiation.GradientField;
34 import org.hipparchus.analysis.differentiation.UnivariateDifferentiableVectorFunction;
35 import org.hipparchus.geometry.euclidean.threed.Rotation;
36 import org.hipparchus.geometry.euclidean.threed.Vector3D;
37 import org.hipparchus.linear.RealMatrix;
38 import org.hipparchus.optim.nonlinear.vector.leastsquares.LevenbergMarquardtOptimizer;
39 import org.hipparchus.random.RandomGenerator;
40 import org.hipparchus.random.Well19937a;
41 import org.hipparchus.util.FastMath;
42 import org.hipparchus.util.Precision;
43 import org.junit.Assert;
44 import org.junit.Test;
45 import org.orekit.Utils;
46 import org.orekit.bodies.BodyShape;
47 import org.orekit.bodies.GeodeticPoint;
48 import org.orekit.bodies.OneAxisEllipsoid;
49 import org.orekit.errors.OrekitException;
50 import org.orekit.errors.OrekitMessages;
51 import org.orekit.estimation.Context;
52 import org.orekit.estimation.EstimationTestUtils;
53 import org.orekit.estimation.leastsquares.BatchLSEstimator;
54 import org.orekit.frames.FieldTransform;
55 import org.orekit.frames.Frame;
56 import org.orekit.frames.FramesFactory;
57 import org.orekit.frames.TopocentricFrame;
58 import org.orekit.frames.Transform;
59 import org.orekit.orbits.OrbitType;
60 import org.orekit.orbits.PositionAngle;
61 import org.orekit.propagation.Propagator;
62 import org.orekit.propagation.conversion.NumericalPropagatorBuilder;
63 import org.orekit.time.AbsoluteDate;
64 import org.orekit.utils.Constants;
65 import org.orekit.utils.FieldPVCoordinates;
66 import org.orekit.utils.IERSConventions;
67 import org.orekit.utils.PVCoordinates;
68 import org.orekit.utils.ParameterDriver;
69
70 public class GroundStationTest {
71
72 @Test
73 public void testEstimateClockOffset() throws IOException, ClassNotFoundException {
74
75 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
76
77 final NumericalPropagatorBuilder propagatorBuilder =
78 context.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true,
79 1.0e-6, 60.0, 0.001);
80
81
82 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
83 propagatorBuilder);
84 final List<ObservedMeasurement<?>> measurements =
85 EstimationTestUtils.createMeasurements(propagator,
86 new RangeMeasurementCreator(context),
87 1.0, 3.0, 300.0);
88
89
90 final TopocentricFrame base = context.stations.get(0).getBaseFrame();
91 final BodyShape parent = base.getParentShape();
92 final double deltaClock = 0.00084532;
93 final String changedSuffix = "-changed";
94 final GroundStation changed = new GroundStation(new TopocentricFrame(parent, base.getPoint(),
95 base.getName() + changedSuffix),
96 context.ut1.getEOPHistory(),
97 context.stations.get(0).getDisplacements());
98
99
100 final BatchLSEstimator estimator = new BatchLSEstimator(new LevenbergMarquardtOptimizer(),
101 propagatorBuilder);
102 for (final ObservedMeasurement<?> measurement : measurements) {
103 final Range range = (Range) measurement;
104 final String name = range.getStation().getBaseFrame().getName() + changedSuffix;
105 if (changed.getBaseFrame().getName().equals(name)) {
106 estimator.addMeasurement(new Range(changed, range.isTwoWay(),
107 range.getDate().shiftedBy(deltaClock),
108 range.getObservedValue()[0],
109 range.getTheoreticalStandardDeviation()[0],
110 range.getBaseWeight()[0],
111 range.getSatellites().get(0)));
112 } else {
113 estimator.addMeasurement(range);
114 }
115 }
116 estimator.setParametersConvergenceThreshold(1.0e-3);
117 estimator.setMaxIterations(100);
118 estimator.setMaxEvaluations(200);
119
120
121 changed.getClockOffsetDriver().setSelected(true);
122 changed.getEastOffsetDriver().setSelected(false);
123 changed.getNorthOffsetDriver().setSelected(false);
124 changed.getZenithOffsetDriver().setSelected(false);
125
126 EstimationTestUtils.checkFit(context, estimator, 2, 3,
127 0.0, 6.7e-7,
128 0.0, 1.8e-6,
129 0.0, 1.3e-7,
130 0.0, 5.9e-11);
131 Assert.assertEquals(deltaClock, changed.getClockOffsetDriver().getValue(), 8.2e-11);
132
133 RealMatrix normalizedCovariances = estimator.getOptimum().getCovariances(1.0e-10);
134 RealMatrix physicalCovariances = estimator.getPhysicalCovariances(1.0e-10);
135 Assert.assertEquals(7, normalizedCovariances.getRowDimension());
136 Assert.assertEquals(7, normalizedCovariances.getColumnDimension());
137 Assert.assertEquals(7, physicalCovariances.getRowDimension());
138 Assert.assertEquals(7, physicalCovariances.getColumnDimension());
139 Assert.assertEquals(4.185e-9, physicalCovariances.getEntry(6, 6), 3.0e-13);
140
141 }
142
143 @Test
144 public void testEstimateStationPosition() throws IOException, ClassNotFoundException {
145
146 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
147
148 final NumericalPropagatorBuilder propagatorBuilder =
149 context.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true,
150 1.0e-6, 60.0, 0.001);
151
152
153 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
154 propagatorBuilder);
155 final List<ObservedMeasurement<?>> measurements =
156 EstimationTestUtils.createMeasurements(propagator,
157 new RangeMeasurementCreator(context),
158 1.0, 3.0, 300.0);
159
160
161 final RandomGenerator random = new Well19937a(0x4adbecfc743bda60l);
162 final TopocentricFrame base = context.stations.get(0).getBaseFrame();
163 final BodyShape parent = base.getParentShape();
164 final Vector3D baseOrigin = parent.transform(base.getPoint());
165 final Vector3D deltaTopo = new Vector3D(2 * random.nextDouble() - 1,
166 2 * random.nextDouble() - 1,
167 2 * random.nextDouble() - 1);
168 final Transform topoToParent = base.getTransformTo(parent.getBodyFrame(), (AbsoluteDate) null);
169 final Vector3D deltaParent = topoToParent.transformVector(deltaTopo);
170 final String movedSuffix = "-moved";
171 final GroundStation moved = new GroundStation(new TopocentricFrame(parent,
172 parent.transform(baseOrigin.subtract(deltaParent),
173 parent.getBodyFrame(),
174 null),
175 base.getName() + movedSuffix),
176 context.ut1.getEOPHistory(),
177 context.stations.get(0).getDisplacements());
178
179
180 final BatchLSEstimator estimator = new BatchLSEstimator(new LevenbergMarquardtOptimizer(),
181 propagatorBuilder);
182 for (final ObservedMeasurement<?> measurement : measurements) {
183 final Range range = (Range) measurement;
184 final String name = range.getStation().getBaseFrame().getName() + movedSuffix;
185 if (moved.getBaseFrame().getName().equals(name)) {
186 estimator.addMeasurement(new Range(moved, range.isTwoWay(), range.getDate(),
187 range.getObservedValue()[0],
188 range.getTheoreticalStandardDeviation()[0],
189 range.getBaseWeight()[0],
190 range.getSatellites().get(0)));
191 } else {
192 estimator.addMeasurement(range);
193 }
194 }
195 estimator.setParametersConvergenceThreshold(1.0e-3);
196 estimator.setMaxIterations(100);
197 estimator.setMaxEvaluations(200);
198
199
200 moved.getClockOffsetDriver().setSelected(false);
201 moved.getEastOffsetDriver().setSelected(true);
202 moved.getNorthOffsetDriver().setSelected(true);
203 moved.getZenithOffsetDriver().setSelected(true);
204
205 EstimationTestUtils.checkFit(context, estimator, 2, 3,
206 0.0, 5.8e-7,
207 0.0, 1.8e-6,
208 0.0, 4.8e-7,
209 0.0, 2.6e-10);
210 Assert.assertEquals(deltaTopo.getX(), moved.getEastOffsetDriver().getValue(), 4.5e-7);
211 Assert.assertEquals(deltaTopo.getY(), moved.getNorthOffsetDriver().getValue(), 6.2e-7);
212 Assert.assertEquals(deltaTopo.getZ(), moved.getZenithOffsetDriver().getValue(), 2.6e-7);
213
214 GeodeticPoint result = moved.getOffsetGeodeticPoint(null);
215
216 GeodeticPoint reference = context.stations.get(0).getBaseFrame().getPoint();
217 Assert.assertEquals(reference.getLatitude(), result.getLatitude(), 1.4e-14);
218 Assert.assertEquals(reference.getLongitude(), result.getLongitude(), 2.9e-14);
219 Assert.assertEquals(reference.getAltitude(), result.getAltitude(), 2.6e-7);
220
221 RealMatrix normalizedCovariances = estimator.getOptimum().getCovariances(1.0e-10);
222 RealMatrix physicalCovariances = estimator.getPhysicalCovariances(1.0e-10);
223 Assert.assertEquals(9, normalizedCovariances.getRowDimension());
224 Assert.assertEquals(9, normalizedCovariances.getColumnDimension());
225 Assert.assertEquals(9, physicalCovariances.getRowDimension());
226 Assert.assertEquals(9, physicalCovariances.getColumnDimension());
227 Assert.assertEquals(0.55431, physicalCovariances.getEntry(6, 6), 1.0e-5);
228 Assert.assertEquals(0.22694, physicalCovariances.getEntry(7, 7), 1.0e-5);
229 Assert.assertEquals(0.13106, physicalCovariances.getEntry(8, 8), 1.0e-5);
230
231 ByteArrayOutputStream bos = new ByteArrayOutputStream();
232 ObjectOutputStream oos = new ObjectOutputStream(bos);
233 oos.writeObject(moved.getEstimatedEarthFrame().getTransformProvider());
234
235 Assert.assertTrue(bos.size() > 155000);
236 Assert.assertTrue(bos.size() < 160000);
237
238 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
239 ObjectInputStream ois = new ObjectInputStream(bis);
240 EstimatedEarthFrameProvider deserialized = (EstimatedEarthFrameProvider) ois.readObject();
241 Assert.assertEquals(moved.getPrimeMeridianOffsetDriver().getValue(),
242 deserialized.getPrimeMeridianOffsetDriver().getValue(),
243 1.0e-15);
244 Assert.assertEquals(moved.getPrimeMeridianDriftDriver().getValue(),
245 deserialized.getPrimeMeridianDriftDriver().getValue(),
246 1.0e-15);
247 Assert.assertEquals(moved.getPolarOffsetXDriver().getValue(),
248 deserialized.getPolarOffsetXDriver().getValue(),
249 1.0e-15);
250 Assert.assertEquals(moved.getPolarDriftXDriver().getValue(),
251 deserialized.getPolarDriftXDriver().getValue(),
252 1.0e-15);
253 Assert.assertEquals(moved.getPolarOffsetYDriver().getValue(),
254 deserialized.getPolarOffsetYDriver().getValue(),
255 1.0e-15);
256 Assert.assertEquals(moved.getPolarDriftYDriver().getValue(),
257 deserialized.getPolarDriftYDriver().getValue(),
258 1.0e-15);
259
260 }
261
262 @Test
263 public void testEstimateEOP() {
264
265 Context linearEOPContext = EstimationTestUtils.eccentricContext("linear-EOP:regular-data/de431-ephemerides:potential:tides");
266
267 final AbsoluteDate refDate = new AbsoluteDate(2000, 2, 24, linearEOPContext.utc);
268 final double dut10 = 0.3079738;
269 final double lod = 0.0011000;
270 final double xp0 = 68450.0e-6;
271 final double xpDot = -50.0e-6;
272 final double yp0 = 60.0e-6;
273 final double ypDot = 2.0e-6;
274 for (double dt = -2 * Constants.JULIAN_DAY; dt < 2 * Constants.JULIAN_DAY; dt += 300.0) {
275 AbsoluteDate date = refDate.shiftedBy(dt);
276 Assert.assertEquals(dut10 - dt * lod / Constants.JULIAN_DAY,
277 linearEOPContext.ut1.getEOPHistory().getUT1MinusUTC(date),
278 1.0e-15);
279 Assert.assertEquals(lod,
280 linearEOPContext.ut1.getEOPHistory().getLOD(date),
281 1.0e-15);
282 Assert.assertEquals((xp0 + xpDot * dt / Constants.JULIAN_DAY) * Constants.ARC_SECONDS_TO_RADIANS,
283 linearEOPContext.ut1.getEOPHistory().getPoleCorrection(date).getXp(),
284 1.0e-15);
285 Assert.assertEquals((yp0 + ypDot * dt / Constants.JULIAN_DAY) * Constants.ARC_SECONDS_TO_RADIANS,
286 linearEOPContext.ut1.getEOPHistory().getPoleCorrection(date).getYp(),
287 1.0e-15);
288 }
289 final NumericalPropagatorBuilder linearPropagatorBuilder =
290 linearEOPContext.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true,
291 1.0e-6, 60.0, 0.001);
292
293
294 final Propagator propagator = EstimationTestUtils.createPropagator(linearEOPContext.initialOrbit,
295 linearPropagatorBuilder);
296 final List<ObservedMeasurement<?>> linearMeasurements =
297 EstimationTestUtils.createMeasurements(propagator,
298 new RangeMeasurementCreator(linearEOPContext),
299 1.0, 5.0, 60.0);
300
301 Utils.clearFactories();
302 Context zeroEOPContext = EstimationTestUtils.eccentricContext("zero-EOP:regular-data/de431-ephemerides:potential:potential:tides");
303 for (double dt = -2 * Constants.JULIAN_DAY; dt < 2 * Constants.JULIAN_DAY; dt += 300.0) {
304 AbsoluteDate date = refDate.shiftedBy(dt);
305 Assert.assertEquals(0.0,
306 zeroEOPContext.ut1.getEOPHistory().getUT1MinusUTC(date),
307 1.0e-15);
308 Assert.assertEquals(0.0,
309 zeroEOPContext.ut1.getEOPHistory().getLOD(date),
310 1.0e-15);
311 Assert.assertEquals(0.0,
312 zeroEOPContext.ut1.getEOPHistory().getPoleCorrection(date).getXp(),
313 1.0e-15);
314 Assert.assertEquals(0.0,
315 zeroEOPContext.ut1.getEOPHistory().getPoleCorrection(date).getYp(),
316 1.0e-15);
317 }
318
319
320 final NumericalPropagatorBuilder zeroPropagatorBuilder =
321 linearEOPContext.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true,
322 1.0e-6, 60.0, 0.001);
323 final BatchLSEstimator estimator = new BatchLSEstimator(new LevenbergMarquardtOptimizer(),
324 zeroPropagatorBuilder);
325 for (final ObservedMeasurement<?> linearMeasurement : linearMeasurements) {
326 Range linearRange = (Range) linearMeasurement;
327 for (final GroundStation station : zeroEOPContext.stations) {
328 if (station.getBaseFrame().getName().equals(linearRange.getStation().getBaseFrame().getName())) {
329 Range zeroRange = new Range(station, linearRange.isTwoWay(),
330 linearRange.getDate(),
331 linearRange.getObservedValue()[0],
332 linearRange.getTheoreticalStandardDeviation()[0],
333 linearRange.getBaseWeight()[0],
334 linearRange.getSatellites().get(0));
335 estimator.addMeasurement(zeroRange);
336 }
337 }
338 }
339 estimator.setParametersConvergenceThreshold(1.0e-3);
340 estimator.setMaxIterations(100);
341 estimator.setMaxEvaluations(200);
342
343
344 GroundStation station = zeroEOPContext.stations.get(0);
345 station.getPrimeMeridianOffsetDriver().setReferenceDate(refDate);
346 station.getPrimeMeridianOffsetDriver().setSelected(true);
347 station.getPrimeMeridianDriftDriver().setSelected(true);
348 station.getPolarOffsetXDriver().setReferenceDate(refDate);
349 station.getPolarOffsetXDriver().setSelected(true);
350 station.getPolarDriftXDriver().setSelected(true);
351 station.getPolarOffsetYDriver().setReferenceDate(refDate);
352 station.getPolarOffsetYDriver().setSelected(true);
353 station.getPolarDriftYDriver().setSelected(true);
354
355
356 for (final ParameterDriver driver : zeroPropagatorBuilder.getOrbitalParametersDrivers().getDrivers()) {
357 driver.setSelected(false);
358 }
359
360 estimator.estimate();
361
362 final double computedDut1 = station.getPrimeMeridianOffsetDriver().getValue() / EstimatedEarthFrameProvider.EARTH_ANGULAR_VELOCITY;
363 final double computedLOD = station.getPrimeMeridianDriftDriver().getValue() * (-Constants.JULIAN_DAY / EstimatedEarthFrameProvider.EARTH_ANGULAR_VELOCITY);
364 final double computedXp = station.getPolarOffsetXDriver().getValue() / Constants.ARC_SECONDS_TO_RADIANS;
365 final double computedXpDot = station.getPolarDriftXDriver().getValue() / Constants.ARC_SECONDS_TO_RADIANS * Constants.JULIAN_DAY;
366 final double computedYp = station.getPolarOffsetYDriver().getValue() / Constants.ARC_SECONDS_TO_RADIANS;
367 final double computedYpDot = station.getPolarDriftYDriver().getValue() / Constants.ARC_SECONDS_TO_RADIANS * Constants.JULIAN_DAY;
368 Assert.assertEquals(0.0, FastMath.abs(dut10 - computedDut1), 4.3e-10);
369 Assert.assertEquals(0.0, FastMath.abs(lod - computedLOD), 4.9e-10);
370 Assert.assertEquals(0.0, FastMath.abs(xp0 - computedXp), 5.7e-9);
371 Assert.assertEquals(0.0, FastMath.abs(xpDot - computedXpDot), 7.3e-9);
372 Assert.assertEquals(0.0, FastMath.abs(yp0 - computedYp), 1.1e-9);
373 Assert.assertEquals(0.0, FastMath.abs(ypDot - computedYpDot), 6.2e-11);
374
375
376
377
378
379
380
381
382
383
384 }
385
386 @Test
387 public void testClockOffsetCartesianDerivativesOctantPxPyPz() {
388 double relativeTolerancePositionValue = 2.3e-15;
389 double relativeTolerancePositionDerivative = 2.5e-10;
390 double relativeToleranceVelocityValue = 3.0e-15;
391 double relativeToleranceVelocityDerivative = 1.7e-10;
392 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 100.0,
393 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
394 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
395 ".*-clock");
396 }
397
398 @Test
399 public void testClockOffsetAngularDerivativesOctantPxPyPz() {
400 double toleranceRotationValue = 1.9e-15;
401 double toleranceRotationDerivative = 4.9e-15;
402 double toleranceRotationRateValue = 1.1e-19;
403 double toleranceRotationRateDerivative = 6.3e-19;
404 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 100.0,
405 toleranceRotationValue, toleranceRotationDerivative,
406 toleranceRotationRateValue, toleranceRotationRateDerivative,
407 ".*-clock");
408 }
409
410 @Test
411 public void testClockOffsetCartesianDerivativesOctantPxPyMz() {
412 double relativeTolerancePositionValue = 1.4e-15;
413 double relativeTolerancePositionDerivative = 1.7e-10;
414 double relativeToleranceVelocityValue = 2.5e-15;
415 double relativeToleranceVelocityDerivative = 1.8e-10;
416 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 100.0,
417 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
418 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
419 ".*-clock");
420 }
421
422 @Test
423 public void testClockOffsetAngularDerivativesOctantPxPyMz() {
424 double toleranceRotationValue = 1.7e-15;
425 double toleranceRotationDerivative = 5.0e-15;
426 double toleranceRotationRateValue = 1.1e-19;
427 double toleranceRotationRateDerivative = 6.3e-19;
428 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 100.0,
429 toleranceRotationValue, toleranceRotationDerivative,
430 toleranceRotationRateValue, toleranceRotationRateDerivative,
431 ".*-clock");
432 }
433
434 @Test
435 public void testClockOffsetCartesianDerivativesOctantPxMyPz() {
436 double relativeTolerancePositionValue = 1.7e-15;
437 double relativeTolerancePositionDerivative = 2.6e-10;
438 double relativeToleranceVelocityValue = 2.8e-15;
439 double relativeToleranceVelocityDerivative = 1.8e-10;
440 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 100.0,
441 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
442 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
443 ".*-clock");
444 }
445
446 @Test
447 public void testClockOffsetAngularDerivativesOctantPxMyPz() {
448 double toleranceRotationValue = 1.6e-15;
449 double toleranceRotationDerivative = 4.9e-15;
450 double toleranceRotationRateValue = 1.1e-19;
451 double toleranceRotationRateDerivative = 6.3e-19;
452 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 100.0,
453 toleranceRotationValue, toleranceRotationDerivative,
454 toleranceRotationRateValue, toleranceRotationRateDerivative,
455 ".*-clock");
456 }
457
458 @Test
459 public void testClockOffsetCartesianDerivativesOctantPxMyMz() {
460 double relativeTolerancePositionValue = 1.5e-15;
461 double relativeTolerancePositionDerivative = 1.6e-10;
462 double relativeToleranceVelocityValue = 2.3e-15;
463 double relativeToleranceVelocityDerivative = 1.7e-10;
464 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 100.0,
465 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
466 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
467 ".*-clock");
468 }
469
470 @Test
471 public void testClockOffsetAngularDerivativesOctantPxMyMz() {
472 double toleranceRotationValue = 1.5e-15;
473 double toleranceRotationDerivative = 5.0e-15;
474 double toleranceRotationRateValue = 1.1e-19;
475 double toleranceRotationRateDerivative = 6.3e-19;
476 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 100.0,
477 toleranceRotationValue, toleranceRotationDerivative,
478 toleranceRotationRateValue, toleranceRotationRateDerivative,
479 ".*-clock");
480 }
481
482 @Test
483 public void testClockOffsetCartesianDerivativesOctantMxPyPz() {
484 double relativeTolerancePositionValue = 1.9e-15;
485 double relativeTolerancePositionDerivative = 2.6e-10;
486 double relativeToleranceVelocityValue = 2.6e-15;
487 double relativeToleranceVelocityDerivative = 2.0e-10;
488 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
489 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
490 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
491 ".*-clock");
492 }
493
494 @Test
495 public void testClockOffsetAngularDerivativesOctantMxPyPz() {
496 double toleranceRotationValue = 1.4e-15;
497 double toleranceRotationDerivative = 5.2e-15;
498 double toleranceRotationRateValue = 1.1e-19;
499 double toleranceRotationRateDerivative = 6.3e-19;
500 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
501 toleranceRotationValue, toleranceRotationDerivative,
502 toleranceRotationRateValue, toleranceRotationRateDerivative,
503 ".*-clock");
504 }
505
506 @Test
507 public void testClockOffsetCartesianDerivativesOctantMxPyMz() {
508 double relativeTolerancePositionValue = 1.9e-15;
509 double relativeTolerancePositionDerivative = 2.6e-10;
510 double relativeToleranceVelocityValue = 2.6e-15;
511 double relativeToleranceVelocityDerivative = 2.0e-10;
512 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
513 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
514 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
515 ".*-clock");
516 }
517
518 @Test
519 public void testClockOffsetAngularDerivativesOctantMxPyMz() {
520 double toleranceRotationValue = 1.4e-15;
521 double toleranceRotationDerivative = 5.2e-15;
522 double toleranceRotationRateValue = 1.1e-19;
523 double toleranceRotationRateDerivative = 6.3e-19;
524 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
525 toleranceRotationValue, toleranceRotationDerivative,
526 toleranceRotationRateValue, toleranceRotationRateDerivative,
527 ".*-clock");
528 }
529
530 @Test
531 public void testClockOffsetCartesianDerivativesOctantMxMyPz() {
532 double relativeTolerancePositionValue = 1.5e-15;
533 double relativeTolerancePositionDerivative = 1.7e-10;
534 double relativeToleranceVelocityValue = 2.9e-15;
535 double relativeToleranceVelocityDerivative = 1.9e-10;
536 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
537 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
538 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
539 ".*-clock");
540 }
541
542 @Test
543 public void testClockOffsetAngularDerivativesOctantMxMyPz() {
544 double toleranceRotationValue = 1.6e-15;
545 double toleranceRotationDerivative = 4.9e-15;
546 double toleranceRotationRateValue = 1.1e-19;
547 double toleranceRotationRateDerivative = 6.3e-19;
548 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
549 toleranceRotationValue, toleranceRotationDerivative,
550 toleranceRotationRateValue, toleranceRotationRateDerivative,
551 ".*-clock");
552 }
553
554 @Test
555 public void testClockOffsetCartesianDerivativesOctantMxMyMz() {
556 double relativeTolerancePositionValue = 1.5e-15;
557 double relativeTolerancePositionDerivative = 1.7e-10;
558 double relativeToleranceVelocityValue = 2.9e-15;
559 double relativeToleranceVelocityDerivative = 1.9e-10;
560 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
561 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
562 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
563 ".*-clock");
564 }
565
566 @Test
567 public void testClockOffsetAngularDerivativesOctantMxMyMz() {
568 double toleranceRotationValue = 1.6e-15;
569 double toleranceRotationDerivative = 4.9e-15;
570 double toleranceRotationRateValue = 1.1e-19;
571 double toleranceRotationRateDerivative = 6.3e-19;
572 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
573 toleranceRotationValue, toleranceRotationDerivative,
574 toleranceRotationRateValue, toleranceRotationRateDerivative,
575 ".*-clock");
576 }
577
578 @Test
579 public void testClockOffsetCartesianDerivativesNearPole() {
580 double relativeTolerancePositionValue = 1.2e-15;
581 double relativeTolerancePositionDerivative = 1.6e-04;
582 double relativeToleranceVelocityValue = 1.0e-13;
583 double relativeToleranceVelocityDerivative = 4.3e-09;
584 doTestCartesianDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 100.0,
585 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
586 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
587 ".*-clock");
588 }
589
590 @Test
591 public void testClockOffsetAngularDerivativesNearPole() {
592 double toleranceRotationValue = 1.5e-15;
593 double toleranceRotationDerivative = 5.7e-15;
594 double toleranceRotationRateValue = 1.1e-19;
595 double toleranceRotationRateDerivative = 6.3e-19;
596 doTestAngularDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 100.0,
597 toleranceRotationValue, toleranceRotationDerivative,
598 toleranceRotationRateValue, toleranceRotationRateDerivative,
599 ".*-clock");
600 }
601
602 @Test
603 public void testStationOffsetCartesianDerivativesOctantPxPyPz() {
604 double relativeTolerancePositionValue = 2.3e-15;
605 double relativeTolerancePositionDerivative = 1.1e-10;
606 double relativeToleranceVelocityValue = 3.3e-15;
607 double relativeToleranceVelocityDerivative = 1.2e-10;
608 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 100.0,
609 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
610 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
611 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
612 }
613
614 @Test
615 public void testStationOffsetAngularDerivativesOctantPxPyPz() {
616 double toleranceRotationValue = 1.9e-15;
617 double toleranceRotationDerivative = 3.1e-18;
618 double toleranceRotationRateValue = 1.5e-19;
619 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
620 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 100.0,
621 toleranceRotationValue, toleranceRotationDerivative,
622 toleranceRotationRateValue, toleranceRotationRateDerivative,
623 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
624 }
625
626 @Test
627 public void testStationOffsetCartesianDerivativesOctantPxPyMz() {
628 double relativeTolerancePositionValue = 1.4e-15;
629 double relativeTolerancePositionDerivative = 7.3e-11;
630 double relativeToleranceVelocityValue = 2.8e-15;
631 double relativeToleranceVelocityDerivative = 1.3e-10;
632 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 100.0,
633 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
634 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
635 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
636 }
637
638 @Test
639 public void testStationOffsetAngularDerivativesOctantPxPyMz() {
640 double toleranceRotationValue = 1.7e-15;
641 double toleranceRotationDerivative = 3.6e-18;
642 double toleranceRotationRateValue = 1.5e-19;
643 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
644 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 100.0,
645 toleranceRotationValue, toleranceRotationDerivative,
646 toleranceRotationRateValue, toleranceRotationRateDerivative,
647 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
648 }
649
650 @Test
651 public void testStationOffsetCartesianDerivativesOctantPxMyPz() {
652 double relativeTolerancePositionValue = 1.7e-15;
653 double relativeTolerancePositionDerivative = 9.0e-11;
654 double relativeToleranceVelocityValue = 2.9e-15;
655 double relativeToleranceVelocityDerivative = 8.8e-11;
656 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 100.0,
657 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
658 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
659 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
660 }
661
662 @Test
663 public void testStationOffsetAngularDerivativesOctantPxMyPz() {
664 double toleranceRotationValue = 1.6e-15;
665 double toleranceRotationDerivative = 3.6e-18;
666 double toleranceRotationRateValue = 1.5e-19;
667 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
668 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 100.0,
669 toleranceRotationValue, toleranceRotationDerivative,
670 toleranceRotationRateValue, toleranceRotationRateDerivative,
671 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
672 }
673
674 @Test
675 public void testStationOffsetCartesianDerivativesOctantPxMyMz() {
676 double relativeTolerancePositionValue = 1.5e-15;
677 double relativeTolerancePositionDerivative = 4.2e-11;
678 double relativeToleranceVelocityValue = 2.7e-15;
679 double relativeToleranceVelocityDerivative = 6.8e-11;
680 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 100.0,
681 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
682 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
683 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
684 }
685
686 @Test
687 public void testStationOffsetAngularDerivativesOctantPxMyMz() {
688 double toleranceRotationValue = 1.6e-15;
689 double toleranceRotationDerivative = 2.6e-18;
690 double toleranceRotationRateValue = 1.5e-19;
691 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
692 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 100.0,
693 toleranceRotationValue, toleranceRotationDerivative,
694 toleranceRotationRateValue, toleranceRotationRateDerivative,
695 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
696 }
697
698 @Test
699 public void testStationOffsetCartesianDerivativesOctantMxPyPz() {
700 double relativeTolerancePositionValue = 1.6e-15;
701 double relativeTolerancePositionDerivative = 9.9e-11;
702 double relativeToleranceVelocityValue = 2.6e-15;
703 double relativeToleranceVelocityDerivative = 9.5e-11;
704 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
705 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
706 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
707 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
708 }
709
710 @Test
711 public void testStationOffsetAngularDerivativesOctantMxPyPz() {
712 double toleranceRotationValue = 1.5e-15;
713 double toleranceRotationDerivative = 3.1e-18;
714 double toleranceRotationRateValue = 1.5e-19;
715 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
716 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
717 toleranceRotationValue, toleranceRotationDerivative,
718 toleranceRotationRateValue, toleranceRotationRateDerivative,
719 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
720 }
721
722 @Test
723 public void testStationOffsetCartesianDerivativesOctantMxPyMz() {
724 double relativeTolerancePositionValue = 1.6e-15;
725 double relativeTolerancePositionDerivative = 9.9e-11;
726 double relativeToleranceVelocityValue = 2.6e-15;
727 double relativeToleranceVelocityDerivative = 9.5e-11;
728 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
729 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
730 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
731 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
732 }
733
734 @Test
735 public void testStationOffsetAngularDerivativesOctantMxPyMz() {
736 double toleranceRotationValue = 1.5e-15;
737 double toleranceRotationDerivative = 3.1e-18;
738 double toleranceRotationRateValue = 1.5e-19;
739 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
740 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 100.0,
741 toleranceRotationValue, toleranceRotationDerivative,
742 toleranceRotationRateValue, toleranceRotationRateDerivative,
743 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
744 }
745
746 @Test
747 public void testStationOffsetCartesianDerivativesOctantMxMyPz() {
748 double relativeTolerancePositionValue = 1.5e-15;
749 double relativeTolerancePositionDerivative = 6.2e-11;
750 double relativeToleranceVelocityValue = 3.2e-15;
751 double relativeToleranceVelocityDerivative = 1.1e-10;
752 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
753 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
754 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
755 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
756 }
757
758 @Test
759 public void testStationOffsetAngularDerivativesOctantMxMyPz() {
760 double toleranceRotationValue = 1.6e-15;
761 double toleranceRotationDerivative = 3.4e-18;
762 double toleranceRotationRateValue = 1.5e-19;
763 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
764 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
765 toleranceRotationValue, toleranceRotationDerivative,
766 toleranceRotationRateValue, toleranceRotationRateDerivative,
767 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
768 }
769
770 @Test
771 public void testStationOffsetCartesianDerivativesOctantMxMyMz() {
772 double relativeTolerancePositionValue = 1.5e-15;
773 double relativeTolerancePositionDerivative = 6.2e-11;
774 double relativeToleranceVelocityValue = 3.2e-15;
775 double relativeToleranceVelocityDerivative = 1.1e-10;
776 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
777 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
778 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
779 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
780 }
781
782 @Test
783 public void testStationOffsetAngularDerivativesOctantMxMyMz() {
784 double toleranceRotationValue = 1.6e-15;
785 double toleranceRotationDerivative = 3.4e-18;
786 double toleranceRotationRateValue = 1.5e-19;
787 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
788 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 100.0,
789 toleranceRotationValue, toleranceRotationDerivative,
790 toleranceRotationRateValue, toleranceRotationRateDerivative,
791 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
792 }
793
794 @Test
795 public void testStationOffsetCartesianDerivativesNearPole() {
796 double relativeTolerancePositionValue = 2.1e-15;
797 double relativeTolerancePositionDerivative = 9.4e-10;
798 double relativeToleranceVelocityValue = 7.5e-14;
799 double relativeToleranceVelocityDerivative = 3.9e-10;
800 doTestCartesianDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 100.0,
801 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
802 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
803 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
804 }
805
806 @Test
807 public void testStationOffsetAngularDerivativesNearPole() {
808 double toleranceRotationValue = 3.9e-15;
809 double toleranceRotationDerivative = 8.0e-02;
810 double toleranceRotationRateValue = 1.5e-19;
811 double toleranceRotationRateDerivative = Precision.SAFE_MIN;
812 doTestAngularDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 100.0,
813 toleranceRotationValue, toleranceRotationDerivative,
814 toleranceRotationRateValue, toleranceRotationRateDerivative,
815 ".*-offset-East", ".*-offset-North", ".*-offset-Zenith");
816 }
817
818 @Test
819 public void testPolarMotionCartesianDerivativesOctantPxPyPz() {
820 double relativeTolerancePositionValue = 2.3e-15;
821 double relativeTolerancePositionDerivative = 7.3e-09;
822 double relativeToleranceVelocityValue = 3.3e-15;
823 double relativeToleranceVelocityDerivative = 4.8e-09;
824 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 1.0,
825 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
826 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
827 "polar-offset-X", "polar-drift-X",
828 "polar-offset-Y", "polar-drift-Y");
829 }
830
831 @Test
832 public void testPolarMotionAngularDerivativesOctantPxPyPz() {
833 double toleranceRotationValue = 1.9e-15;
834 double toleranceRotationDerivative = 6.6e-09;
835 double toleranceRotationRateValue = 1.5e-19;
836 double toleranceRotationRateDerivative = 2.2e-13;
837 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 0.2,
838 toleranceRotationValue, toleranceRotationDerivative,
839 toleranceRotationRateValue, toleranceRotationRateDerivative,
840 "polar-offset-X", "polar-drift-X",
841 "polar-offset-Y", "polar-drift-Y");
842 }
843
844 @Test
845 public void testPolarMotionCartesianDerivativesOctantPxPyMz() {
846 double relativeTolerancePositionValue = 1.4e-15;
847 double relativeTolerancePositionDerivative = 4.1e-09;
848 double relativeToleranceVelocityValue = 2.8e-15;
849 double relativeToleranceVelocityDerivative = 4.7e-09;
850 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 1.0,
851 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
852 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
853 "polar-offset-X", "polar-drift-X",
854 "polar-offset-Y", "polar-drift-Y");
855 }
856
857 @Test
858 public void testPolarMotionAngularDerivativesOctantPxPyMz() {
859 double toleranceRotationValue = 1.7e-15;
860 double toleranceRotationDerivative = 6.9e-09;
861 double toleranceRotationRateValue = 1.5e-19;
862 double toleranceRotationRateDerivative = 2.2e-13;
863 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 0.2,
864 toleranceRotationValue, toleranceRotationDerivative,
865 toleranceRotationRateValue, toleranceRotationRateDerivative,
866 "polar-offset-X", "polar-drift-X",
867 "polar-offset-Y", "polar-drift-Y");
868 }
869
870 @Test
871 public void testPolarMotionCartesianDerivativesOctantPxMyPz() {
872 double relativeTolerancePositionValue = 1.7e-15;
873 double relativeTolerancePositionDerivative = 7.8e-09;
874 double relativeToleranceVelocityValue = 2.9e-15;
875 double relativeToleranceVelocityDerivative = 4.4e-09;
876 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 1.0,
877 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
878 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
879 "polar-offset-X", "polar-drift-X",
880 "polar-offset-Y", "polar-drift-Y");
881 }
882
883 @Test
884 public void testPolarMotionAngularDerivativesOctantPxMyPz() {
885 double toleranceRotationValue = 1.6e-15;
886 double toleranceRotationDerivative = 7.5e-09;
887 double toleranceRotationRateValue = 1.5e-19;
888 double toleranceRotationRateDerivative = 2.2e-13;
889 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 0.2,
890 toleranceRotationValue, toleranceRotationDerivative,
891 toleranceRotationRateValue, toleranceRotationRateDerivative,
892 "polar-offset-X", "polar-drift-X",
893 "polar-offset-Y", "polar-drift-Y");
894 }
895
896 @Test
897 public void testPolarMotionCartesianDerivativesOctantPxMyMz() {
898 double relativeTolerancePositionValue = 1.5e-15;
899 double relativeTolerancePositionDerivative = 4.1e-09;
900 double relativeToleranceVelocityValue = 2.7e-15;
901 double relativeToleranceVelocityDerivative = 4.4e-09;
902 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 1.0,
903 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
904 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
905 "polar-offset-X", "polar-drift-X",
906 "polar-offset-Y", "polar-drift-Y");
907 }
908
909 @Test
910 public void testPolarMotionAngularDerivativesOctantPxMyMz() {
911 double toleranceRotationValue = 1.6e-15;
912 double toleranceRotationDerivative = 7.3e-09;
913 double toleranceRotationRateValue = 1.5e-19;
914 double toleranceRotationRateDerivative = 2.2e-13;
915 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 0.2,
916 toleranceRotationValue, toleranceRotationDerivative,
917 toleranceRotationRateValue, toleranceRotationRateDerivative,
918 "polar-offset-X", "polar-drift-X",
919 "polar-offset-Y", "polar-drift-Y");
920 }
921
922 @Test
923 public void testPolarMotionCartesianDerivativesOctantMxPyPz() {
924 double relativeTolerancePositionValue = 1.6e-15;
925 double relativeTolerancePositionDerivative = 8.4e-09;
926 double relativeToleranceVelocityValue = 2.6e-15;
927 double relativeToleranceVelocityDerivative = 5.0e-09;
928 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 1.0,
929 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
930 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
931 "polar-offset-X", "polar-drift-X",
932 "polar-offset-Y", "polar-drift-Y");
933 }
934
935 @Test
936 public void testPolarMotionAngularDerivativesOctantMxPyPz() {
937 double toleranceRotationValue = 1.4e-15;
938 double toleranceRotationDerivative = 6.3e-09;
939 double toleranceRotationRateValue = 1.5e-19;
940 double toleranceRotationRateDerivative = 2.2e-13;
941 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 0.2,
942 toleranceRotationValue, toleranceRotationDerivative,
943 toleranceRotationRateValue, toleranceRotationRateDerivative,
944 "polar-offset-X", "polar-drift-X",
945 "polar-offset-Y", "polar-drift-Y");
946 }
947
948 @Test
949 public void testPolarMotionCartesianDerivativesOctantMxPyMz() {
950 double relativeTolerancePositionValue = 1.6e-15;
951 double relativeTolerancePositionDerivative = 8.4e-09;
952 double relativeToleranceVelocityValue = 2.6e-15;
953 double relativeToleranceVelocityDerivative = 5.0e-09;
954 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 1.0,
955 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
956 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
957 "polar-offset-X", "polar-drift-X",
958 "polar-offset-Y", "polar-drift-Y");
959 }
960
961 @Test
962 public void testPolarMotionAngularDerivativesOctantMxPyMz() {
963 double toleranceRotationValue = 1.4e-15;
964 double toleranceRotationDerivative = 6.3e-09;
965 double toleranceRotationRateValue = 1.5e-19;
966 double toleranceRotationRateDerivative = 2.2e-13;
967 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 0.2,
968 toleranceRotationValue, toleranceRotationDerivative,
969 toleranceRotationRateValue, toleranceRotationRateDerivative,
970 "polar-offset-X", "polar-drift-X",
971 "polar-offset-Y", "polar-drift-Y");
972 }
973
974 @Test
975 public void testPolarMotionCartesianDerivativesOctantMxMyPz() {
976 double relativeTolerancePositionValue = 1.5e-15;
977 double relativeTolerancePositionDerivative = 5.0e-09;
978 double relativeToleranceVelocityValue = 3.2e-15;
979 double relativeToleranceVelocityDerivative = 5.3e-09;
980 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 1.0,
981 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
982 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
983 "polar-offset-X", "polar-drift-X",
984 "polar-offset-Y", "polar-drift-Y");
985 }
986
987 @Test
988 public void testPolarMotionAngularDerivativesOctantMxMyPz() {
989 double toleranceRotationValue = 1.6e-15;
990 double toleranceRotationDerivative = 7.7e-09;
991 double toleranceRotationRateValue = 1.5e-19;
992 double toleranceRotationRateDerivative = 2.2e-13;
993 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 0.2,
994 toleranceRotationValue, toleranceRotationDerivative,
995 toleranceRotationRateValue, toleranceRotationRateDerivative,
996 "polar-offset-X", "polar-drift-X",
997 "polar-offset-Y", "polar-drift-Y");
998 }
999
1000 @Test
1001 public void testPolarMotionCartesianDerivativesOctantMxMyMz() {
1002 double relativeTolerancePositionValue = 1.5e-15;
1003 double relativeTolerancePositionDerivative = 5.0e-09;
1004 double relativeToleranceVelocityValue = 3.2e-15;
1005 double relativeToleranceVelocityDerivative = 5.3e-09;
1006 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 1.0,
1007 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1008 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1009 "polar-offset-X", "polar-drift-X",
1010 "polar-offset-Y", "polar-drift-Y");
1011 }
1012
1013 @Test
1014 public void testPolarMotionAngularDerivativesOctantMxMyMz() {
1015 double toleranceRotationValue = 1.6e-15;
1016 double toleranceRotationDerivative = 7.7e-09;
1017 double toleranceRotationRateValue = 1.5e-19;
1018 double toleranceRotationRateDerivative = 2.2e-13;
1019 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 0.2,
1020 toleranceRotationValue, toleranceRotationDerivative,
1021 toleranceRotationRateValue, toleranceRotationRateDerivative,
1022 "polar-offset-X", "polar-drift-X",
1023 "polar-offset-Y", "polar-drift-Y");
1024 }
1025
1026 @Test
1027 public void testPolarMotionCartesianDerivativesNearPole() {
1028 double relativeTolerancePositionValue = 1.2e-15;
1029 double relativeTolerancePositionDerivative = 5.7e-09;
1030 double relativeToleranceVelocityValue = 9.4e-13;
1031 double relativeToleranceVelocityDerivative = 1.2e-09;
1032 doTestCartesianDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 1.0,
1033 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1034 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1035 "polar-offset-X", "polar-drift-X",
1036 "polar-offset-Y", "polar-drift-Y");
1037 }
1038
1039 @Test
1040 public void testPolarMotionAngularDerivativesNearPole() {
1041 double toleranceRotationValue = 1.5e-15;
1042 double toleranceRotationDerivative = 6.5e-09;
1043 double toleranceRotationRateValue = 1.5e-19;
1044 double toleranceRotationRateDerivative = 2.2e-13;
1045 doTestAngularDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 0.2,
1046 toleranceRotationValue, toleranceRotationDerivative,
1047 toleranceRotationRateValue, toleranceRotationRateDerivative,
1048 "polar-offset-X", "polar-drift-X",
1049 "polar-offset-Y", "polar-drift-Y");
1050 }
1051
1052 @Test
1053 public void testPrimeMeridianCartesianDerivativesOctantPxPyPz() {
1054 double relativeTolerancePositionValue = 2.3e-15;
1055 double relativeTolerancePositionDerivative = 5.7e-09;
1056 double relativeToleranceVelocityValue = 3.3e-15;
1057 double relativeToleranceVelocityDerivative = 2.7e-09;
1058 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 1.0,
1059 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1060 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1061 "prime-meridian-offset", "prime-meridian-drift");
1062 }
1063
1064 @Test
1065 public void testPrimeMeridianAngularDerivativesOctantPxPyPz() {
1066 double toleranceRotationValue = 1.9e-15;
1067 double toleranceRotationDerivative = 4.9e-09;
1068 double toleranceRotationRateValue = 1.5e-19;
1069 double toleranceRotationRateDerivative = 2.0e-13;
1070 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(20), 1200.0, 0.2,
1071 toleranceRotationValue, toleranceRotationDerivative,
1072 toleranceRotationRateValue, toleranceRotationRateDerivative,
1073 "prime-meridian-offset", "prime-meridian-drift");
1074 }
1075
1076 @Test
1077 public void testPrimeMeridianCartesianDerivativesOctantPxPyMz() {
1078 double relativeTolerancePositionValue = 1.4e-15;
1079 double relativeTolerancePositionDerivative = 3.1e-09;
1080 double relativeToleranceVelocityValue = 2.8e-15;
1081 double relativeToleranceVelocityDerivative = 3.3e-09;
1082 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 1.0,
1083 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1084 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1085 "prime-meridian-offset", "prime-meridian-drift");
1086 }
1087
1088 @Test
1089 public void testPrimeMeridianAngularDerivativesOctantPxPyMz() {
1090 double toleranceRotationValue = 1.7e-15;
1091 double toleranceRotationDerivative = 5.7e-09;
1092 double toleranceRotationRateValue = 1.5e-19;
1093 double toleranceRotationRateDerivative = 2.0e-13;
1094 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(20), 1200.0, 0.2,
1095 toleranceRotationValue, toleranceRotationDerivative,
1096 toleranceRotationRateValue, toleranceRotationRateDerivative,
1097 "prime-meridian-offset", "prime-meridian-drift");
1098 }
1099
1100 @Test
1101 public void testPrimeMeridianCartesianDerivativesOctantPxMyPz() {
1102 double relativeTolerancePositionValue = 1.7e-15;
1103 double relativeTolerancePositionDerivative = 5.3e-09;
1104 double relativeToleranceVelocityValue = 2.9e-15;
1105 double relativeToleranceVelocityDerivative = 3.4e-09;
1106 doTestCartesianDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 1.0,
1107 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1108 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1109 "prime-meridian-offset", "prime-meridian-drift");
1110 }
1111
1112 @Test
1113 public void testPrimeMeridianAngularDerivativesOctantPxMyPz() {
1114 double toleranceRotationValue = 1.6e-15;
1115 double toleranceRotationDerivative = 6.4e-09;
1116 double toleranceRotationRateValue = 1.5e-19;
1117 double toleranceRotationRateDerivative = 2.0e-13;
1118 doTestAngularDerivatives(FastMath.toRadians(35), FastMath.toRadians(-20), 1200.0, 0.2,
1119 toleranceRotationValue, toleranceRotationDerivative,
1120 toleranceRotationRateValue, toleranceRotationRateDerivative,
1121 "prime-meridian-offset", "prime-meridian-drift");
1122 }
1123
1124 @Test
1125 public void testPrimeMeridianCartesianDerivativesOctantPxMyMz() {
1126 double relativeTolerancePositionValue = 1.5e-15;
1127 double relativeTolerancePositionDerivative = 3.1e-09;
1128 double relativeToleranceVelocityValue = 2.7e-15;
1129 double relativeToleranceVelocityDerivative = 3.0e-09;
1130 doTestCartesianDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 1.0,
1131 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1132 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1133 "prime-meridian-offset", "prime-meridian-drift");
1134 }
1135
1136 @Test
1137 public void testPrimeMeridianAngularDerivativesOctantPxMyMz() {
1138 double toleranceRotationValue = 1.5e-15;
1139 double toleranceRotationDerivative = 6.3e-09;
1140 double toleranceRotationRateValue = 1.5e-19;
1141 double toleranceRotationRateDerivative = 2.0e-13;
1142 doTestAngularDerivatives(FastMath.toRadians(-35), FastMath.toRadians(-20), 1200.0, 0.2,
1143 toleranceRotationValue, toleranceRotationDerivative,
1144 toleranceRotationRateValue, toleranceRotationRateDerivative,
1145 "prime-meridian-offset", "prime-meridian-drift");
1146 }
1147
1148 @Test
1149 public void testPrimeMeridianCartesianDerivativesOctantMxPyPz() {
1150 double relativeTolerancePositionValue = 1.6e-15;
1151 double relativeTolerancePositionDerivative = 5.5e-09;
1152 double relativeToleranceVelocityValue = 2.6e-15;
1153 double relativeToleranceVelocityDerivative = 2.8e-09;
1154 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 1.0,
1155 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1156 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1157 "prime-meridian-offset", "prime-meridian-drift");
1158 }
1159
1160 @Test
1161 public void testPrimeMeridianAngularDerivativesOctantMxPyPz() {
1162 double toleranceRotationValue = 1.5e-15;
1163 double toleranceRotationDerivative = 6.8e-09;
1164 double toleranceRotationRateValue = 1.5e-19;
1165 double toleranceRotationRateDerivative = 2.0e-13;
1166 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 0.2,
1167 toleranceRotationValue, toleranceRotationDerivative,
1168 toleranceRotationRateValue, toleranceRotationRateDerivative,
1169 "prime-meridian-offset", "prime-meridian-drift");
1170 }
1171
1172 @Test
1173 public void testPrimeMeridianCartesianDerivativesOctantMxPyMz() {
1174 double relativeTolerancePositionValue = 1.6e-15;
1175 double relativeTolerancePositionDerivative = 5.5e-09;
1176 double relativeToleranceVelocityValue = 2.6e-15;
1177 double relativeToleranceVelocityDerivative = 2.8e-09;
1178 doTestCartesianDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 1.0,
1179 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1180 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1181 "prime-meridian-offset", "prime-meridian-drift");
1182 }
1183
1184 @Test
1185 public void testPrimeMeridianAngularDerivativesOctantMxPyMz() {
1186 double toleranceRotationValue = 1.5e-15;
1187 double toleranceRotationDerivative = 6.8e-09;
1188 double toleranceRotationRateValue = 1.5e-19;
1189 double toleranceRotationRateDerivative = 2.0e-13;
1190 doTestAngularDerivatives(FastMath.toRadians(150), FastMath.toRadians(20), 1200.0, 0.2,
1191 toleranceRotationValue, toleranceRotationDerivative,
1192 toleranceRotationRateValue, toleranceRotationRateDerivative,
1193 "prime-meridian-offset", "prime-meridian-drift");
1194 }
1195
1196 @Test
1197 public void testPrimeMeridianCartesianDerivativesOctantMxMyPz() {
1198 double relativeTolerancePositionValue = 1.5e-15;
1199 double relativeTolerancePositionDerivative = 3.1e-09;
1200 double relativeToleranceVelocityValue = 3.2e-15;
1201 double relativeToleranceVelocityDerivative = 3.2e-09;
1202 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 1.0,
1203 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1204 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1205 "prime-meridian-offset", "prime-meridian-drift");
1206 }
1207
1208 @Test
1209 public void testPrimeMeridianAngularDerivativesOctantMxMyPz() {
1210 double toleranceRotationValue = 1.6e-15;
1211 double toleranceRotationDerivative = 6.2e-09;
1212 double toleranceRotationRateValue = 1.5e-19;
1213 double toleranceRotationRateDerivative = 2.0e-13;
1214 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 0.2,
1215 toleranceRotationValue, toleranceRotationDerivative,
1216 toleranceRotationRateValue, toleranceRotationRateDerivative,
1217 "prime-meridian-offset", "prime-meridian-drift");
1218 }
1219
1220 @Test
1221 public void testPrimeMeridianCartesianDerivativesOctantMxMyMz() {
1222 double relativeTolerancePositionValue = 1.5e-15;
1223 double relativeTolerancePositionDerivative = 3.1e-09;
1224 double relativeToleranceVelocityValue = 3.2e-15;
1225 double relativeToleranceVelocityDerivative = 3.2e-09;
1226 doTestCartesianDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 1.0,
1227 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1228 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1229 "prime-meridian-offset", "prime-meridian-drift");
1230 }
1231
1232 @Test
1233 public void testPrimeMeridianAngularDerivativesOctantMxMyMz() {
1234 double toleranceRotationValue = 1.6e-15;
1235 double toleranceRotationDerivative = 6.2e-09;
1236 double toleranceRotationRateValue = 1.5e-19;
1237 double toleranceRotationRateDerivative = 2.0e-13;
1238 doTestAngularDerivatives(FastMath.toRadians(-150), FastMath.toRadians(-20), 1200.0, 0.2,
1239 toleranceRotationValue, toleranceRotationDerivative,
1240 toleranceRotationRateValue, toleranceRotationRateDerivative,
1241 "prime-meridian-offset", "prime-meridian-drift");
1242 }
1243
1244 @Test
1245 public void testPrimeMeridianCartesianDerivativesNearPole() {
1246 double relativeTolerancePositionValue = 1.2e-15;
1247 double relativeTolerancePositionDerivative = 1.6e-03;
1248 double relativeToleranceVelocityValue = 5.8e-14;
1249 double relativeToleranceVelocityDerivative = 2.6e-08;
1250 doTestCartesianDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 1.0,
1251 relativeTolerancePositionValue, relativeTolerancePositionDerivative,
1252 relativeToleranceVelocityValue, relativeToleranceVelocityDerivative,
1253 "prime-meridian-offset", "prime-meridian-drift");
1254 }
1255
1256 @Test
1257 public void testPrimeMeridianAngularDerivativesNearPole() {
1258 double toleranceRotationValue = 1.5e-15;
1259 double toleranceRotationDerivative = 7.3e-09;
1260 double toleranceRotationRateValue = 1.5e-19;
1261 double toleranceRotationRateDerivative = 2.0e-13;
1262 doTestAngularDerivatives(FastMath.toRadians(89.99995), FastMath.toRadians(90), 1200.0, 0.2,
1263 toleranceRotationValue, toleranceRotationDerivative,
1264 toleranceRotationRateValue, toleranceRotationRateDerivative,
1265 "prime-meridian-offset", "prime-meridian-drift");
1266 }
1267
1268 @Test
1269 public void testNoReferenceDateGradient() {
1270 Utils.setDataRoot("regular-data");
1271 final Frame eme2000 = FramesFactory.getEME2000();
1272 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
1273 final OneAxisEllipsoid earth =
1274 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1275 Constants.WGS84_EARTH_FLATTENING,
1276 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
1277 final GroundStation station = new GroundStation(new TopocentricFrame(earth,
1278 new GeodeticPoint(0.1, 0.2, 100),
1279 "dummy"));
1280 try {
1281 station.getOffsetToInertial(eme2000, date);
1282 Assert.fail("an exception should have been thrown");
1283 } catch (OrekitException oe) {
1284 Assert.assertEquals(OrekitMessages.NO_REFERENCE_DATE_FOR_PARAMETER, oe.getSpecifier());
1285 Assert.assertEquals("prime-meridian-offset", (String) oe.getParts()[0]);
1286 }
1287
1288 try {
1289 int freeParameters = 9;
1290 Map<String, Integer> indices = new HashMap<>();
1291 for (final ParameterDriver driver : Arrays.asList(station.getPrimeMeridianOffsetDriver(),
1292 station.getPrimeMeridianDriftDriver(),
1293 station.getPolarOffsetXDriver(),
1294 station.getPolarDriftXDriver(),
1295 station.getPolarOffsetYDriver(),
1296 station.getPolarDriftYDriver(),
1297 station.getClockOffsetDriver(),
1298 station.getEastOffsetDriver(),
1299 station.getNorthOffsetDriver(),
1300 station.getZenithOffsetDriver())) {
1301 indices.put(driver.getName(), indices.size());
1302 }
1303 station.getOffsetToInertial(eme2000, date, freeParameters, indices);
1304 Assert.fail("an exception should have been thrown");
1305 } catch (OrekitException oe) {
1306 Assert.assertEquals(OrekitMessages.NO_REFERENCE_DATE_FOR_PARAMETER, oe.getSpecifier());
1307 Assert.assertEquals("prime-meridian-offset", (String) oe.getParts()[0]);
1308 }
1309
1310 }
1311
1312 private void doTestCartesianDerivatives(double latitude, double longitude, double altitude, double stepFactor,
1313 double relativeTolerancePositionValue, double relativeTolerancePositionDerivative,
1314 double relativeToleranceVelocityValue, double relativeToleranceVelocityDerivative,
1315 String... parameterPattern) {
1316 Utils.setDataRoot("regular-data");
1317 final Frame eme2000 = FramesFactory.getEME2000();
1318 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
1319 final AbsoluteDate date0 = date.shiftedBy(50000);
1320 final OneAxisEllipsoid earth =
1321 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1322 Constants.WGS84_EARTH_FLATTENING,
1323 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
1324 final GroundStation station = new GroundStation(new TopocentricFrame(earth,
1325 new GeodeticPoint(latitude, longitude, altitude),
1326 "dummy"));
1327 final GradientField gradientField = GradientField.getField(parameterPattern.length);
1328 ParameterDriver[] selectedDrivers = new ParameterDriver[parameterPattern.length];
1329 UnivariateDifferentiableVectorFunction[] dFCartesian = new UnivariateDifferentiableVectorFunction[parameterPattern.length];
1330 final ParameterDriver[] allDrivers = selectAllDrivers(station);
1331 for (ParameterDriver driver : allDrivers) {
1332 driver.setReferenceDate(date0);
1333 }
1334 Map<String, Integer> indices = new HashMap<>();
1335 for (int k = 0; k < dFCartesian.length; ++k) {
1336 for (int i = 0; i < allDrivers.length; ++i) {
1337 if (allDrivers[i].getName().matches(parameterPattern[k])) {
1338 selectedDrivers[k] = allDrivers[i];
1339 dFCartesian[k] = differentiatedStationPV(station, eme2000, date, selectedDrivers[k], stepFactor);
1340 indices.put(selectedDrivers[k].getName(), k);
1341 }
1342 }
1343 };
1344
1345 RandomGenerator generator = new Well19937a(0x084d58a19c498a54l);
1346
1347 double maxPositionValueRelativeError = 0;
1348 double maxPositionDerivativeRelativeError = 0;
1349 double maxVelocityValueRelativeError = 0;
1350 double maxVelocityDerivativeRelativeError = 0;
1351 for (int i = 0; i < 1000; ++i) {
1352
1353
1354 ParameterDriver changed = allDrivers[generator.nextInt(allDrivers.length)];
1355 changed.setNormalizedValue(2 * generator.nextDouble() - 1);
1356
1357
1358 FieldTransform<Gradient> t = station.getOffsetToInertial(eme2000, date, parameterPattern.length, indices);
1359 FieldPVCoordinates<Gradient> pv = t.transformPVCoordinates(FieldPVCoordinates.getZero(gradientField));
1360 for (int k = 0; k < dFCartesian.length; ++k) {
1361
1362
1363 Gradient[] refCartesian = dFCartesian[k].value(Gradient.variable(1, 0, selectedDrivers[k].getValue()));
1364
1365
1366 final Vector3D refP = new Vector3D(refCartesian[0].getValue(),
1367 refCartesian[1].getValue(),
1368 refCartesian[2].getValue());
1369 final Vector3D resP = new Vector3D(pv.getPosition().getX().getValue(),
1370 pv.getPosition().getY().getValue(),
1371 pv.getPosition().getZ().getValue());
1372 maxPositionValueRelativeError =
1373 FastMath.max(maxPositionValueRelativeError, Vector3D.distance(refP, resP) / refP.getNorm());
1374 final Vector3D refPD = new Vector3D(refCartesian[0].getPartialDerivative(0),
1375 refCartesian[1].getPartialDerivative(0),
1376 refCartesian[2].getPartialDerivative(0));
1377 final Vector3D resPD = new Vector3D(pv.getPosition().getX().getPartialDerivative(k),
1378 pv.getPosition().getY().getPartialDerivative(k),
1379 pv.getPosition().getZ().getPartialDerivative(k));
1380 maxPositionDerivativeRelativeError =
1381 FastMath.max(maxPositionDerivativeRelativeError, Vector3D.distance(refPD, resPD) / refPD.getNorm());
1382
1383
1384 final Vector3D refV = new Vector3D(refCartesian[3].getValue(),
1385 refCartesian[4].getValue(),
1386 refCartesian[5].getValue());
1387 final Vector3D resV = new Vector3D(pv.getVelocity().getX().getValue(),
1388 pv.getVelocity().getY().getValue(),
1389 pv.getVelocity().getZ().getValue());
1390 maxVelocityValueRelativeError =
1391 FastMath.max(maxVelocityValueRelativeError, Vector3D.distance(refV, resV) / refV.getNorm());
1392 final Vector3D refVD = new Vector3D(refCartesian[3].getPartialDerivative(0),
1393 refCartesian[4].getPartialDerivative(0),
1394 refCartesian[5].getPartialDerivative(0));
1395 final Vector3D resVD = new Vector3D(pv.getVelocity().getX().getPartialDerivative(k),
1396 pv.getVelocity().getY().getPartialDerivative(k),
1397 pv.getVelocity().getZ().getPartialDerivative(k));
1398 maxVelocityDerivativeRelativeError =
1399 FastMath.max(maxVelocityDerivativeRelativeError, Vector3D.distance(refVD, resVD) / refVD.getNorm());
1400
1401 }
1402
1403 }
1404
1405 if (maxPositionValueRelativeError > relativeTolerancePositionValue ||
1406 maxPositionDerivativeRelativeError > relativeTolerancePositionDerivative ||
1407 maxVelocityValueRelativeError > relativeToleranceVelocityValue ||
1408 maxVelocityDerivativeRelativeError > relativeToleranceVelocityDerivative) {
1409 print("relativeTolerancePositionValue", maxPositionValueRelativeError);
1410 print("relativeTolerancePositionDerivative", maxPositionDerivativeRelativeError);
1411 print("relativeToleranceVelocityValue", maxVelocityValueRelativeError);
1412 print("relativeToleranceVelocityDerivative", maxVelocityDerivativeRelativeError);
1413 }
1414 Assert.assertEquals(0.0, maxPositionValueRelativeError, relativeTolerancePositionValue);
1415 Assert.assertEquals(0.0, maxPositionDerivativeRelativeError, relativeTolerancePositionDerivative);
1416 Assert.assertEquals(0.0, maxVelocityValueRelativeError, relativeToleranceVelocityValue);
1417 Assert.assertEquals(0.0, maxVelocityDerivativeRelativeError, relativeToleranceVelocityDerivative);
1418
1419 }
1420
1421 private void doTestAngularDerivatives(double latitude, double longitude, double altitude, double stepFactor,
1422 double toleranceRotationValue, double toleranceRotationDerivative,
1423 double toleranceRotationRateValue, double toleranceRotationRateDerivative,
1424 String... parameterPattern) {
1425 Utils.setDataRoot("regular-data");
1426 final Frame eme2000 = FramesFactory.getEME2000();
1427 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
1428 final AbsoluteDate date0 = date.shiftedBy(50000);
1429 final OneAxisEllipsoid earth =
1430 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1431 Constants.WGS84_EARTH_FLATTENING,
1432 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
1433 final GroundStation station = new GroundStation(new TopocentricFrame(earth,
1434 new GeodeticPoint(latitude, longitude, altitude),
1435 "dummy"));
1436 ParameterDriver[] selectedDrivers = new ParameterDriver[parameterPattern.length];
1437 UnivariateDifferentiableVectorFunction[] dFAngular = new UnivariateDifferentiableVectorFunction[parameterPattern.length];
1438 final ParameterDriver[] allDrivers = selectAllDrivers(station);
1439 for (ParameterDriver driver : allDrivers) {
1440 driver.setReferenceDate(date0);
1441 }
1442 Map<String, Integer> indices = new HashMap<>();
1443 for (int k = 0; k < dFAngular.length; ++k) {
1444 for (int i = 0; i < allDrivers.length; ++i) {
1445 if (allDrivers[i].getName().matches(parameterPattern[k])) {
1446 selectedDrivers[k] = allDrivers[i];
1447 dFAngular[k] = differentiatedTransformAngular(station, eme2000, date, selectedDrivers[k], stepFactor);
1448 indices.put(selectedDrivers[k].getName(), k);
1449 }
1450 }
1451 };
1452 RandomGenerator generator = new Well19937a(0xa01a1d8fe5d80af7l);
1453
1454 double maxRotationValueError = 0;
1455 double maxRotationDerivativeError = 0;
1456 double maxRotationRateValueError = 0;
1457 double maxRotationRateDerivativeError = 0;
1458 for (int i = 0; i < 1000; ++i) {
1459
1460
1461 ParameterDriver changed = allDrivers[generator.nextInt(allDrivers.length)];
1462 changed.setNormalizedValue(2 * generator.nextDouble() - 1);
1463
1464
1465 FieldTransform<Gradient> t = station.getOffsetToInertial(eme2000, date, parameterPattern.length, indices);
1466 for (int k = 0; k < dFAngular.length; ++k) {
1467
1468
1469 Gradient[] refAngular = dFAngular[k].value(Gradient.variable(1, 0, selectedDrivers[k].getValue()));
1470
1471
1472 final Rotation refQ = new Rotation(refAngular[0].getValue(),
1473 refAngular[1].getValue(),
1474 refAngular[2].getValue(),
1475 refAngular[3].getValue(),
1476 true);
1477 final Rotation resQ = t.getRotation().toRotation();
1478 maxRotationValueError = FastMath.max(maxRotationValueError, Rotation.distance(refQ, resQ));
1479 double sign = FastMath.copySign(1.0,
1480 refAngular[0].getValue() * t.getRotation().getQ0().getValue() +
1481 refAngular[1].getValue() * t.getRotation().getQ1().getValue() +
1482 refAngular[2].getValue() * t.getRotation().getQ2().getValue() +
1483 refAngular[3].getValue() * t.getRotation().getQ3().getValue());
1484 maxRotationDerivativeError = FastMath.max(maxRotationDerivativeError,
1485 FastMath.abs(sign * refAngular[0].getPartialDerivative(0) -
1486 t.getRotation().getQ0().getPartialDerivative(k)));
1487 maxRotationDerivativeError = FastMath.max(maxRotationDerivativeError,
1488 FastMath.abs(sign * refAngular[1].getPartialDerivative(0) -
1489 t.getRotation().getQ1().getPartialDerivative(k)));
1490 maxRotationDerivativeError = FastMath.max(maxRotationDerivativeError,
1491 FastMath.abs(sign * refAngular[2].getPartialDerivative(0) -
1492 t.getRotation().getQ2().getPartialDerivative(k)));
1493 maxRotationDerivativeError = FastMath.max(maxRotationDerivativeError,
1494 FastMath.abs(sign * refAngular[3].getPartialDerivative(0) -
1495 t.getRotation().getQ3().getPartialDerivative(k)));
1496
1497
1498 final Vector3D refRate = new Vector3D(refAngular[4].getValue(), refAngular[5].getValue(), refAngular[6].getValue());
1499 final Vector3D resRate = t.getRotationRate().toVector3D();
1500 final Vector3D refRateD = new Vector3D(refAngular[4].getPartialDerivative(0),
1501 refAngular[5].getPartialDerivative(0),
1502 refAngular[6].getPartialDerivative(0));
1503 final Vector3D resRateD = new Vector3D(t.getRotationRate().getX().getPartialDerivative(k),
1504 t.getRotationRate().getY().getPartialDerivative(k),
1505 t.getRotationRate().getZ().getPartialDerivative(k));
1506 maxRotationRateValueError = FastMath.max(maxRotationRateValueError, Vector3D.distance(refRate, resRate));
1507 maxRotationRateDerivativeError = FastMath.max(maxRotationRateDerivativeError, Vector3D.distance(refRateD, resRateD));
1508
1509 }
1510
1511 }
1512
1513 if (maxRotationValueError > toleranceRotationValue ||
1514 maxRotationDerivativeError > toleranceRotationDerivative ||
1515 maxRotationRateValueError > toleranceRotationRateValue ||
1516 maxRotationRateDerivativeError > toleranceRotationRateDerivative) {
1517 print("toleranceRotationValue", maxRotationValueError);
1518 print("toleranceRotationDerivative", maxRotationDerivativeError);
1519 print("toleranceRotationRateValue", maxRotationRateValueError);
1520 print("toleranceRotationRateDerivative", maxRotationRateDerivativeError);
1521 }
1522 Assert.assertEquals(0.0, maxRotationValueError, toleranceRotationValue);
1523 Assert.assertEquals(0.0, maxRotationDerivativeError, toleranceRotationDerivative);
1524 Assert.assertEquals(0.0, maxRotationRateValueError, toleranceRotationRateValue);
1525 Assert.assertEquals(0.0, maxRotationRateDerivativeError, toleranceRotationRateDerivative);
1526
1527 }
1528 private void print(String name, double v) {
1529 if (v < Precision.SAFE_MIN) {
1530 System.out.format(Locale.US, " double %-35s = Precision.SAFE_MIN;%n", name);
1531 } else {
1532 double s = FastMath.pow(10.0, 1 - FastMath.floor(FastMath.log(v) / FastMath.log(10.0)));
1533 System.out.format(Locale.US, " double %-35s = %8.1e;%n",
1534 name, FastMath.ceil(s * v) / s);
1535 }
1536 }
1537
1538 private UnivariateDifferentiableVectorFunction differentiatedStationPV(final GroundStation station,
1539 final Frame eme2000,
1540 final AbsoluteDate date,
1541 final ParameterDriver driver,
1542 final double stepFactor) {
1543
1544 final FiniteDifferencesDifferentiator differentiator =
1545 new FiniteDifferencesDifferentiator(5, stepFactor * driver.getScale());
1546
1547 return differentiator.differentiate(new UnivariateVectorFunction() {
1548 @Override
1549 public double[] value(double x) {
1550 final double[] result = new double[6];
1551 try {
1552 final double previouspI = driver.getValue();
1553 driver.setValue(x);
1554 Transform t = station.getOffsetToInertial(eme2000, date);
1555 driver.setValue(previouspI);
1556 PVCoordinates stationPV = t.transformPVCoordinates(PVCoordinates.ZERO);
1557 result[ 0] = stationPV.getPosition().getX();
1558 result[ 1] = stationPV.getPosition().getY();
1559 result[ 2] = stationPV.getPosition().getZ();
1560 result[ 3] = stationPV.getVelocity().getX();
1561 result[ 4] = stationPV.getVelocity().getY();
1562 result[ 5] = stationPV.getVelocity().getZ();
1563 } catch (OrekitException oe) {
1564 Assert.fail(oe.getLocalizedMessage());
1565 }
1566 return result;
1567 }
1568 });
1569 }
1570
1571 private UnivariateDifferentiableVectorFunction differentiatedTransformAngular(final GroundStation station,
1572 final Frame eme2000,
1573 final AbsoluteDate date,
1574 final ParameterDriver driver,
1575 final double stepFactor) {
1576
1577 final FiniteDifferencesDifferentiator differentiator =
1578 new FiniteDifferencesDifferentiator(5, stepFactor * driver.getScale());
1579
1580 return differentiator.differentiate(new UnivariateVectorFunction() {
1581 private double previous0 = Double.NaN;
1582 private double previous1 = Double.NaN;
1583 private double previous2 = Double.NaN;
1584 private double previous3 = Double.NaN;
1585 @Override
1586 public double[] value(double x) {
1587 final double[] result = new double[7];
1588 try {
1589 final double previouspI = driver.getValue();
1590 driver.setValue(x);
1591 Transform t = station.getOffsetToInertial(eme2000, date);
1592 driver.setValue(previouspI);
1593 final double sign;
1594 if (Double.isNaN(previous0)) {
1595 sign = +1;
1596 } else {
1597 sign = FastMath.copySign(1.0,
1598 previous0 * t.getRotation().getQ0() +
1599 previous1 * t.getRotation().getQ1() +
1600 previous2 * t.getRotation().getQ2() +
1601 previous3 * t.getRotation().getQ3());
1602 }
1603 previous0 = sign * t.getRotation().getQ0();
1604 previous1 = sign * t.getRotation().getQ1();
1605 previous2 = sign * t.getRotation().getQ2();
1606 previous3 = sign * t.getRotation().getQ3();
1607 result[0] = previous0;
1608 result[1] = previous1;
1609 result[2] = previous2;
1610 result[3] = previous3;
1611 result[4] = t.getRotationRate().getX();
1612 result[5] = t.getRotationRate().getY();
1613 result[6] = t.getRotationRate().getZ();
1614 } catch (OrekitException oe) {
1615 Assert.fail(oe.getLocalizedMessage());
1616 }
1617 return result;
1618 }
1619 });
1620 }
1621
1622 private ParameterDriver[] selectAllDrivers(final GroundStation station) {
1623 return new ParameterDriver[] {
1624 station.getPrimeMeridianOffsetDriver(),
1625 station.getPrimeMeridianDriftDriver(),
1626 station.getPolarOffsetXDriver(),
1627 station.getPolarDriftXDriver(),
1628 station.getPolarOffsetYDriver(),
1629 station.getPolarDriftYDriver(),
1630 station.getClockOffsetDriver(),
1631 station.getEastOffsetDriver(),
1632 station.getNorthOffsetDriver(),
1633 station.getZenithOffsetDriver()
1634 };
1635 }
1636
1637 }
1638