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.getNonInterpolatingEOPHistory(), ut1);
83 }
84
85
86 @Override
87 public Transform getTransform(final AbsoluteDate date) {
88
89
90 final double correctedERA = era.value(date);
91
92
93 final double lod = (eopHistory == null) ? 0.0 : eopHistory.getLOD(date);
94 final double omp = AVE * (1 - lod / Constants.JULIAN_DAY);
95 final Vector3D rotationRate = new Vector3D(omp, Vector3D.PLUS_K);
96
97
98 final Rotation rotation = new Rotation(Vector3D.PLUS_K, correctedERA, RotationConvention.FRAME_TRANSFORM);
99 return new Transform(date, rotation, rotationRate);
100
101 }
102
103
104 @Override
105 public StaticTransform getStaticTransform(final AbsoluteDate date) {
106
107 final double correctedERA = era.value(date);
108
109 final Rotation rotation = new Rotation(
110 Vector3D.PLUS_K,
111 correctedERA,
112 RotationConvention.FRAME_TRANSFORM);
113 return StaticTransform.of(date, rotation);
114 }
115
116
117 @Override
118 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
119
120
121 final T correctedERA = era.value(date);
122
123
124 final T lod = (eopHistory == null) ? date.getField().getZero() : eopHistory.getLOD(date);
125 final T omp = lod.divide(Constants.JULIAN_DAY).subtract(1).multiply(-AVE);
126 final FieldVector3D<T> rotationRate = new FieldVector3D<>(omp, Vector3D.PLUS_K);
127
128
129 final FieldRotation<T> rotation = new FieldRotation<>(FieldVector3D.getPlusK(date.getField()),
130 correctedERA,
131 RotationConvention.FRAME_TRANSFORM);
132 return new FieldTransform<>(date, rotation, rotationRate);
133
134 }
135
136
137
138
139
140 public double getEarthRotationAngle(final AbsoluteDate date) {
141 return MathUtils.normalizeAngle(era.value(date), 0);
142 }
143
144
145
146
147
148
149
150 @DefaultDataContext
151 private Object writeReplace() {
152 return new DataTransferObject(eopHistory);
153 }
154
155
156 @DefaultDataContext
157 private static class DataTransferObject implements Serializable {
158
159
160 private static final long serialVersionUID = 20131209L;
161
162
163 private final EOPHistory eopHistory;
164
165
166
167
168 DataTransferObject(final EOPHistory eopHistory) {
169 this.eopHistory = eopHistory;
170 }
171
172
173
174
175 private Object readResolve() {
176 try {
177
178 return new TIRFProvider(eopHistory,
179 DataContext.getDefault().getTimeScales().getUT1(eopHistory));
180 } catch (OrekitException oe) {
181 throw new OrekitInternalError(oe);
182 }
183 }
184
185 }
186
187 }