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