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.io.Serializable;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Rotation;
25 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.hipparchus.util.FastMath;
28 import org.orekit.annotation.DefaultDataContext;
29 import org.orekit.data.DataContext;
30 import org.orekit.errors.OrekitException;
31 import org.orekit.errors.OrekitInternalError;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.FieldAbsoluteDate;
34 import org.orekit.time.TimeScalarFunction;
35 import org.orekit.time.TimeScales;
36 import org.orekit.time.TimeVectorFunction;
37 import org.orekit.utils.IERSConventions;
38
39
40
41
42
43
44
45
46
47 class TEMEProvider implements EOPBasedTransformProvider {
48
49
50 private static final long serialVersionUID = 20131209L;
51
52
53 private final IERSConventions conventions;
54
55
56 private final EOPHistory eopHistory;
57
58
59 private final transient TimeScalarFunction obliquityFunction;
60
61
62 private final transient TimeVectorFunction nutationFunction;
63
64
65
66
67
68
69
70
71 TEMEProvider(final IERSConventions conventions,
72 final EOPHistory eopHistory,
73 final TimeScales timeScales) {
74 this.conventions = conventions;
75 this.eopHistory = eopHistory;
76 this.obliquityFunction = conventions.getMeanObliquityFunction(timeScales);
77 this.nutationFunction = conventions.getNutationFunction(timeScales);
78 }
79
80
81
82
83
84
85
86
87
88 private TEMEProvider(final IERSConventions conventions,
89 final EOPHistory eopHistory,
90 final TimeScalarFunction obliquityFunction,
91 final TimeVectorFunction nutationFunction) {
92 this.conventions = conventions;
93 this.eopHistory = eopHistory;
94 this.obliquityFunction = obliquityFunction;
95 this.nutationFunction = nutationFunction;
96 }
97
98
99 @Override
100 public EOPHistory getEOPHistory() {
101 return eopHistory;
102 }
103
104
105 @Override
106 public TEMEProvider getNonInterpolatingProvider() {
107 return new TEMEProvider(conventions, eopHistory.getEOPHistoryWithoutCachedTidalCorrection(),
108 obliquityFunction, nutationFunction);
109 }
110
111
112 @Override
113 public Transform getTransform(final AbsoluteDate date) {
114 final double eqe = getEquationOfEquinoxes(date);
115 return new Transform(date, new Rotation(Vector3D.PLUS_K, eqe, RotationConvention.FRAME_TRANSFORM));
116 }
117
118
119 @Override
120 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
121 final T eqe = getEquationOfEquinoxes(date);
122 return new FieldTransform<>(date, new FieldRotation<>(FieldVector3D.getPlusK(date.getField()),
123 eqe,
124 RotationConvention.FRAME_TRANSFORM));
125 }
126
127
128
129
130
131 private double getEquationOfEquinoxes(final AbsoluteDate date) {
132
133
134 final double[] angles = nutationFunction.value(date);
135
136
137 double dPsi = angles[0];
138
139 if (eopHistory != null) {
140
141 final double[] correction = eopHistory.getEquinoxNutationCorrection(date);
142 dPsi += correction[0];
143 }
144
145
146 final double moe = obliquityFunction.value(date);
147
148
149 final double eqe = dPsi * FastMath.cos(moe);
150
151
152 return eqe + angles[2];
153
154 }
155
156
157
158
159
160
161 private <T extends CalculusFieldElement<T>> T getEquationOfEquinoxes(final FieldAbsoluteDate<T> date) {
162
163
164 final T[] angles = nutationFunction.value(date);
165
166
167 T dPsi = angles[0];
168
169 if (eopHistory != null) {
170
171 final T[] correction = eopHistory.getEquinoxNutationCorrection(date);
172 dPsi = dPsi.add(correction[0]);
173 }
174
175
176 final T moe = obliquityFunction.value(date);
177
178
179 final T eqe = dPsi.multiply(moe.cos());
180
181
182 return eqe.add(angles[2]);
183
184 }
185
186
187
188
189
190
191
192 @DefaultDataContext
193 private Object writeReplace() {
194 return new DataTransferObject(conventions, eopHistory);
195 }
196
197
198 @DefaultDataContext
199 private static class DataTransferObject implements Serializable {
200
201
202 private static final long serialVersionUID = 20131209L;
203
204
205 private final IERSConventions conventions;
206
207
208 private final EOPHistory eopHistory;
209
210
211
212
213
214 DataTransferObject(final IERSConventions conventions, final EOPHistory eopHistory) {
215 this.conventions = conventions;
216 this.eopHistory = eopHistory;
217 }
218
219
220
221
222 private Object readResolve() {
223 try {
224
225 return new TEMEProvider(conventions, eopHistory,
226 DataContext.getDefault().getTimeScales());
227 } catch (OrekitException oe) {
228 throw new OrekitInternalError(oe);
229 }
230 }
231
232 }
233
234 }