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 TransformProvider {
43
44
45 private final IERSConventions conventions;
46
47
48 private final TimeVectorFunction precessionFunction;
49
50
51 private final Rotation r4;
52
53
54 private final 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 @Override
73 public Transform getTransform(final AbsoluteDate date) {
74
75
76 final double[] angles = precessionFunction.value(date);
77
78
79 final Rotation precession = r4.compose(new Rotation(RotationOrder.ZXZ, RotationConvention.FRAME_TRANSFORM,
80 -angles[0], -angles[1], angles[2]),
81 RotationConvention.FRAME_TRANSFORM);
82
83
84 return new Transform(date, precession);
85
86 }
87
88
89 @SuppressWarnings("unchecked")
90 @Override
91 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
92
93
94 final T[] angles = precessionFunction.value(date);
95
96 final FieldRotation<T> fR4;
97 synchronized (fieldR4) {
98 fR4 = (FieldRotation<T>) fieldR4.computeIfAbsent(date.getField(),
99 f -> new FieldRotation<>((Field<T>) f, r4));
100 }
101
102
103 final FieldRotation<T> precession = fR4.compose(new FieldRotation<>(RotationOrder.ZXZ, RotationConvention.FRAME_TRANSFORM,
104 angles[0].negate(),
105 angles[1].negate(),
106 angles[2]),
107 RotationConvention.FRAME_TRANSFORM);
108
109
110 return new FieldTransform<>(date, precession);
111
112 }
113
114 }