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 TimeVectorFunction precessionFunction;
46
47
48 private final Rotation r4;
49
50
51 private final Map<Field<? extends CalculusFieldElement<?>>, FieldRotation<? extends CalculusFieldElement<?>>> fieldR4;
52
53
54
55
56
57 MODProvider(final IERSConventions conventions, final TimeScales timeScales) {
58 this.precessionFunction = conventions.getPrecessionFunction(timeScales);
59 final TimeScalarFunction epsilonAFunction =
60 conventions.getMeanObliquityFunction(timeScales);
61 final AbsoluteDate date0 = conventions.getNutationReferenceEpoch(timeScales);
62 final double epsilon0 = epsilonAFunction.value(date0);
63 r4 = new Rotation(Vector3D.PLUS_I, epsilon0, RotationConvention.FRAME_TRANSFORM);
64 fieldR4 = new HashMap<>();
65 }
66
67
68 @Override
69 public Transform getTransform(final AbsoluteDate date) {
70
71
72 final double[] angles = precessionFunction.value(date);
73
74
75 final Rotation precession = r4.compose(new Rotation(RotationOrder.ZXZ, RotationConvention.FRAME_TRANSFORM,
76 -angles[0], -angles[1], angles[2]),
77 RotationConvention.FRAME_TRANSFORM);
78
79
80 return new Transform(date, precession);
81
82 }
83
84
85 @SuppressWarnings("unchecked")
86 @Override
87 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
88
89
90 final T[] angles = precessionFunction.value(date);
91
92 final FieldRotation<T> fR4;
93 synchronized (fieldR4) {
94 fR4 = (FieldRotation<T>) fieldR4.computeIfAbsent(date.getField(),
95 f -> new FieldRotation<>((Field<T>) f, r4));
96 }
97
98
99 final FieldRotation<T> precession = fR4.compose(new FieldRotation<>(RotationOrder.ZXZ, RotationConvention.FRAME_TRANSFORM,
100 angles[0].negate(),
101 angles[1].negate(),
102 angles[2]),
103 RotationConvention.FRAME_TRANSFORM);
104
105
106 return new FieldTransform<>(date, precession);
107
108 }
109
110 }