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.orekit.annotation.DefaultDataContext;
28 import org.orekit.data.DataContext;
29 import org.orekit.errors.OrekitException;
30 import org.orekit.errors.OrekitInternalError;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.FieldAbsoluteDate;
33 import org.orekit.time.TimeScalarFunction;
34 import org.orekit.time.TimeScale;
35 import org.orekit.time.TimeScales;
36 import org.orekit.utils.Constants;
37 import org.orekit.utils.IERSConventions;
38
39
40
41
42
43
44
45
46
47 public class GTODProvider implements EOPBasedTransformProvider {
48
49
50 private static final long serialVersionUID = 20141228L;
51
52
53 private static final double AVE = 7.292115146706979e-5;
54
55
56 private final IERSConventions conventions;
57
58
59 private final EOPHistory eopHistory;
60
61
62 private final transient TimeScalarFunction gastFunction;
63
64
65
66
67
68
69
70 protected GTODProvider(final IERSConventions conventions,
71 final EOPHistory eopHistory,
72 final TimeScales timeScales) {
73 final TimeScale ut1 = eopHistory == null ?
74 timeScales.getUTC() :
75 timeScales.getUT1(eopHistory.getConventions(), eopHistory.isSimpleEop());
76 this.conventions = conventions;
77 this.eopHistory = eopHistory;
78 this.gastFunction = conventions.getGASTFunction(ut1, eopHistory, timeScales);
79 }
80
81
82
83
84
85
86
87
88 private GTODProvider(final IERSConventions conventions,
89 final EOPHistory eopHistory,
90 final TimeScalarFunction gastFunction) {
91 this.conventions = conventions;
92 this.eopHistory = eopHistory;
93 this.gastFunction = gastFunction;
94 }
95
96
97 @Override
98 public EOPHistory getEOPHistory() {
99 return eopHistory;
100 }
101
102
103 @Override
104 public GTODProvider getNonInterpolatingProvider() {
105 return new GTODProvider(conventions, eopHistory.getEOPHistoryWithoutCachedTidalCorrection(),
106 gastFunction);
107 }
108
109
110 @Override
111 public Transform getTransform(final AbsoluteDate date) {
112 return new Transform(date, getRotation(date), getRotationRate(date));
113 }
114
115
116 @Override
117 public KinematicTransform getKinematicTransform(final AbsoluteDate date) {
118 return KinematicTransform.of(date, getRotation(date), getRotationRate(date));
119 }
120
121
122 @Override
123 public StaticTransform getStaticTransform(final AbsoluteDate date) {
124 return StaticTransform.of(date, getRotation(date));
125 }
126
127
128
129
130
131
132 private Rotation getRotation(final AbsoluteDate date) {
133
134 final double gast = gastFunction.value(date);
135
136
137 return new Rotation(Vector3D.PLUS_K, gast, RotationConvention.FRAME_TRANSFORM);
138 }
139
140
141
142
143
144
145 private Vector3D getRotationRate(final AbsoluteDate date) {
146
147 final double lod = (eopHistory == null) ? 0.0 : eopHistory.getLOD(date);
148 final double omp = AVE * (1 - lod / Constants.JULIAN_DAY);
149 return new Vector3D(omp, Vector3D.PLUS_K);
150 }
151
152
153 @Override
154 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
155 return new FieldTransform<>(date, getRotation(date), getRotationRate(date));
156 }
157
158
159 @Override
160 public <T extends CalculusFieldElement<T>> FieldKinematicTransform<T> getKinematicTransform(final FieldAbsoluteDate<T> date) {
161 return FieldKinematicTransform.of(date, getRotation(date), getRotationRate(date));
162 }
163
164
165 @Override
166 public <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {
167 return FieldStaticTransform.of(date, getRotation(date));
168 }
169
170
171
172
173
174
175
176 private <T extends CalculusFieldElement<T>> FieldRotation<T> getRotation(final FieldAbsoluteDate<T> date) {
177
178 final T gast = gastFunction.value(date);
179
180
181 return new FieldRotation<>(FieldVector3D.getPlusK(date.getField()), gast, RotationConvention.FRAME_TRANSFORM);
182 }
183
184
185
186
187
188
189
190 private <T extends CalculusFieldElement<T>> FieldVector3D<T> getRotationRate(final FieldAbsoluteDate<T> date) {
191
192 final T lod = (eopHistory == null) ? date.getField().getZero() : eopHistory.getLOD(date);
193 final T omp = lod.multiply(-1.0 / Constants.JULIAN_DAY).add(1).multiply(AVE);
194 return new FieldVector3D<>(date.getField().getZero(),
195 date.getField().getZero(),
196 date.getField().getZero().add(omp));
197 }
198
199
200
201
202
203
204
205 @DefaultDataContext
206 private Object writeReplace() {
207 return new DataTransferObject(conventions, eopHistory);
208 }
209
210
211 @DefaultDataContext
212 private static class DataTransferObject implements Serializable {
213
214
215 private static final long serialVersionUID = 20131209L;
216
217
218 private final IERSConventions conventions;
219
220
221 private final EOPHistory eopHistory;
222
223
224
225
226
227 DataTransferObject(final IERSConventions conventions, final EOPHistory eopHistory) {
228 this.conventions = conventions;
229 this.eopHistory = eopHistory;
230 }
231
232
233
234
235 private Object readResolve() {
236 try {
237
238 return new GTODProvider(conventions, eopHistory,
239 DataContext.getDefault().getTimeScales());
240 } catch (OrekitException oe) {
241 throw new OrekitInternalError(oe);
242 }
243 }
244
245 }
246
247 }