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 <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
106
107
108 final T correctedERA = era.value(date);
109
110
111 final T lod = (eopHistory == null) ? date.getField().getZero() : eopHistory.getLOD(date);
112 final T omp = lod.divide(Constants.JULIAN_DAY).subtract(1).multiply(-AVE);
113 final FieldVector3D<T> rotationRate = new FieldVector3D<>(omp, Vector3D.PLUS_K);
114
115
116 final FieldRotation<T> rotation = new FieldRotation<>(FieldVector3D.getPlusK(date.getField()),
117 correctedERA,
118 RotationConvention.FRAME_TRANSFORM);
119 return new FieldTransform<>(date, rotation, rotationRate);
120
121 }
122
123
124
125
126
127 public double getEarthRotationAngle(final AbsoluteDate date) {
128 return MathUtils.normalizeAngle(era.value(date), 0);
129 }
130
131
132
133
134
135
136
137 @DefaultDataContext
138 private Object writeReplace() {
139 return new DataTransferObject(eopHistory);
140 }
141
142
143 @DefaultDataContext
144 private static class DataTransferObject implements Serializable {
145
146
147 private static final long serialVersionUID = 20131209L;
148
149
150 private final EOPHistory eopHistory;
151
152
153
154
155 DataTransferObject(final EOPHistory eopHistory) {
156 this.eopHistory = eopHistory;
157 }
158
159
160
161
162 private Object readResolve() {
163 try {
164
165 return new TIRFProvider(eopHistory,
166 DataContext.getDefault().getTimeScales().getUT1(eopHistory));
167 } catch (OrekitException oe) {
168 throw new OrekitInternalError(oe);
169 }
170 }
171
172 }
173
174 }