1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.frames;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.Field;
24 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
25 import org.hipparchus.geometry.euclidean.threed.Rotation;
26 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
27 import org.hipparchus.geometry.euclidean.threed.RotationOrder;
28 import org.hipparchus.geometry.euclidean.threed.Vector3D;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.time.TimeScalarFunction;
32 import org.orekit.time.TimeScales;
33 import org.orekit.time.TimeVectorFunction;
34 import org.orekit.utils.IERSConventions;
35
36
37
38
39
40
41
42 class MODProvider implements FieldBasedTransformProvider {
43
44
45 private final IERSConventions conventions;
46
47
48 private final transient TimeVectorFunction precessionFunction;
49
50
51 private final Rotation r4;
52
53
54 private final transient Map<Field<? extends CalculusFieldElement<?>>, FieldRotation<? extends CalculusFieldElement<?>>> fieldR4;
55
56
57
58
59
60 MODProvider(final IERSConventions conventions, final TimeScales timeScales) {
61 this.conventions = conventions;
62 this.precessionFunction = conventions.getPrecessionFunction(timeScales);
63 final TimeScalarFunction epsilonAFunction =
64 conventions.getMeanObliquityFunction(timeScales);
65 final AbsoluteDate date0 = conventions.getNutationReferenceEpoch(timeScales);
66 final double epsilon0 = epsilonAFunction.value(date0);
67 r4 = new Rotation(Vector3D.PLUS_I, epsilon0, RotationConvention.FRAME_TRANSFORM);
68 fieldR4 = new HashMap<>();
69 }
70
71
72
73
74
75
76 public <T extends CalculusFieldElement<T>> FieldRotation<T> getRotation(final FieldAbsoluteDate<T> date) {
77
78
79 final T[] angles = precessionFunction.value(date);
80
81
82 return getR4(date.getField()).compose(
83 new FieldRotation<>(RotationOrder.ZXZ, RotationConvention.FRAME_TRANSFORM,
84 angles[0].negate(), angles[1].negate(), angles[2]),
85 RotationConvention.FRAME_TRANSFORM);
86
87 }
88
89
90
91
92
93
94 @SuppressWarnings("unchecked")
95 private <T extends CalculusFieldElement<T>> FieldRotation<T> getR4(final Field<T> field) {
96 synchronized (fieldR4) {
97 return (FieldRotation<T>) fieldR4.computeIfAbsent(field, f -> new FieldRotation<>(field, r4));
98 }
99 }
100
101 }