1 /* Copyright 2002-2025 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.frames;
18
19 import java.util.Optional;
20 import java.util.stream.Stream;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.Field;
24 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.hipparchus.geometry.euclidean.threed.Rotation;
27 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
28 import org.hipparchus.geometry.euclidean.threed.Vector3D;
29 import org.hipparchus.util.Precision;
30 import org.orekit.annotation.DefaultDataContext;
31 import org.orekit.data.DataContext;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.DateTimeComponents;
34 import org.orekit.time.FieldAbsoluteDate;
35 import org.orekit.time.TimeScale;
36 import org.orekit.utils.Constants;
37 import org.orekit.utils.FieldPVCoordinates;
38 import org.orekit.utils.PVCoordinates;
39
40
41 /** Transformation class for geodetic systems.
42 *
43 * <p>The Helmert transformation is mainly used to convert between various
44 * realizations of geodetic frames, for example in the ITRF family.</p>
45 *
46 * <p>The original Helmert transformation is a 14 parameters transform that
47 * includes translation, velocity, rotation, rotation rate and scale factor.
48 * The scale factor is useful for coordinates near Earth surface, but it
49 * cannot be extended to outer space as it would correspond to a non-unitary
50 * transform. Therefore, the scale factor is <em>not</em> used here.
51 *
52 * <p>Instances of this class are guaranteed to be immutable.</p>
53 *
54 * @author Luc Maisonobe
55 * @since 5.1
56 */
57 public class HelmertTransformation implements TransformProvider {
58
59 /** Enumerate for predefined Helmert transformations. */
60 public enum Predefined {
61
62 // see https://itrf.ign.fr/docs/solutions/itrf2020/Transfo-ITRF2020_TRFs.txt
63 // SOLUTION Tx Ty Tz D Rx Ry Rz EPOCH
64 // UNITS----------> mm mm mm ppb .001" .001" .001"
65 // . . . . . . .
66 // RATES Tx Ty Tz D Rx Ry Rz
67 // UNITS----------> mm/y mm/y mm/y ppb/y .001"/y .001"/y .001"/y
68 // -----------------------------------------------------------------------------------------
69 // ITRF2014 -1.4 -0.9 1.4 -0.42 0.00 0.00 0.00 2015.0
70 // rates 0.0 -0.1 0.2 0.00 0.00 0.00 0.00
71 // ITRF2008 0.2 1.0 3.3 -0.29 0.00 0.00 0.00 2015.0
72 // rates 0.0 -0.1 0.1 0.03 0.00 0.00 0.00
73 // ITRF2005 2.7 0.1 -1.4 0.65 0.00 0.00 0.00 2015.0
74 // rates 0.3 -0.1 0.1 0.03 0.00 0.00 0.00
75 // ITRF2000 -0.2 0.8 -34.2 2.25 0.00 0.00 0.00 2015.0
76 // rates 0.1 0.0 -1.7 0.11 0.00 0.00 0.00
77 // ITRF97 6.5 -3.9 -77.9 3.98 0.00 0.00 0.36 2015.0
78 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
79 // ITRF96 6.5 -3.9 -77.9 3.98 0.00 0.00 0.36 2015.0
80 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
81 // ITRF94 6.5 -3.9 -77.9 3.98 0.00 0.00 0.36 2015.0
82 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
83 // ITRF93 -65.8 1.9 -71.3 4.47 -3.36 -4.33 0.75 2015.0
84 // rates -2.8 -0.2 -2.3 0.12 -0.11 -0.19 0.07
85 // ITRF92 14.5 -1.9 -85.9 3.27 0.00 0.00 0.36 2015.0
86 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
87 // ITRF91 26.5 12.1 -91.9 4.67 0.00 0.00 0.36 2015.0
88 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
89 // ITRF90 24.5 8.1 -107.9 4.97 0.00 0.00 0.36 2015.0
90 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
91 // ITRF89 29.5 32.1 -145.9 8.37 0.00 0.00 0.36 2015.0
92 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
93 // ITRF88 24.5 -3.9 -169.9 11.47 0.10 0.00 0.36 2015.0
94 // rates 0.1 -0.6 -3.1 0.12 0.00 0.00 0.02
95 // _________________________________________________________________________________________
96
97 /** Transformation from ITRF 2020 To ITRF 2014. */
98 ITRF_2020_TO_ITRF_2014(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2014, 2015,
99 -1.4, -0.9, 1.4, 0.00, 0.00, 0.00,
100 0.0, -0.1, 0.2, 0.00, 0.00, 0.00),
101
102 /** Transformation from ITRF 2020 To ITRF 2008. */
103 ITRF_2020_TO_ITRF_2008(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2008, 2015,
104 0.2, 1.0, 3.3, 0.00, 0.00, 0.00,
105 0.0, -0.1, 0.1, 0.00, 0.00, 0.00),
106
107 /** Transformation from ITRF 2020 To ITRF 2005. */
108 ITRF_2020_TO_ITRF_2005(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2005, 2015,
109 2.7, 0.1, -1.4, 0.00, 0.00, 0.00,
110 0.3, -0.1, 0.1, 0.00, 0.00, 0.00),
111
112 /** Transformation from ITRF 2020 To ITRF 2000. */
113 ITRF_2020_TO_ITRF_2000(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2000, 2015,
114 -0.2, 0.8, -34.2, 0.00, 0.00, 0.00,
115 0.1, 0.0, -1.7, 0.00, 0.00, 0.00),
116
117 /** Transformation from ITRF 2020 To ITRF 97. */
118 ITRF_2020_TO_ITRF_1997(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1997, 2015,
119 6.5, -3.9, -77.9, 0.00, 0.00, 0.36,
120 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
121
122 /** Transformation from ITRF 2020 To ITRF 96. */
123 ITRF_2020_TO_ITRF_1996(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1996, 2015,
124 6.5, -3.9, -77.9, 0.00, 0.00, 0.36,
125 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
126
127 /** Transformation from ITRF 2020 To ITRF 94. */
128 ITRF_2020_TO_ITRF_1994(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1994, 2015,
129 6.5, -3.9, -77.9, 0.00, 0.00, 0.36,
130 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
131
132 /** Transformation from ITRF 2020 To ITRF 93. */
133 ITRF_2020_TO_ITRF_1993(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1993, 2015,
134 -65.8, 1.9, -71.3, -3.36, -4.33, 0.75,
135 -2.8, -0.2, -2.3, -0.11, -0.19, 0.07),
136
137 /** Transformation from ITRF 2020 To ITRF 92. */
138 ITRF_2020_TO_ITRF_1992(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1992, 2015,
139 14.5, -1.9, -85.9, 0.00, 0.00, 0.36,
140 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
141
142 /** Transformation from ITRF 2020 To ITRF 91. */
143 ITRF_2020_TO_ITRF_1991(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1991, 2015,
144 26.5, 12.1, -91.9, 0.00, 0.00, 0.36,
145 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
146
147 /** Transformation from ITRF 2020 To ITRF 90. */
148 ITRF_2020_TO_ITRF_1990(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1990, 2015,
149 24.5, 8.1, -107.9, 0.00, 0.00, 0.36,
150 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
151
152 /** Transformation from ITRF 2020 To ITRF 89. */
153 ITRF_2020_TO_ITRF_1989(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1989, 2015,
154 29.5, 32.1, -145.9, 0.00, 0.00, 0.36,
155 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
156
157 /** Transformation from ITRF 2020 To ITRF 88. */
158 ITRF_2020_TO_ITRF_1988(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1988, 2015,
159 24.5, -3.9, -169.9, 0.10, 0.00, 0.36,
160 0.1, -0.6, -3.1, 0.00, 0.00, 0.02),
161
162 // see http://itrf.ign.fr/doc_ITRF/Transfo-ITRF2014_ITRFs.txt
163 // SOLUTION Tx Ty Tz D Rx Ry Rz EPOCH
164 // UNITS----------> mm mm mm ppb .001" .001" .001"
165 // . . . . . . .
166 // RATES Tx Ty Tz D Rx Ry Rz
167 // UNITS----------> mm/y mm/y mm/y ppb/y .001"/y .001"/y .001"/y
168 // -----------------------------------------------------------------------------------------
169 // ITRF2008 1.6 1.9 2.4 -0.02 0.00 0.00 0.00 2010.0
170 // rates 0.0 0.0 -0.1 0.03 0.00 0.00 0.00
171 // ITRF2005 2.6 1.0 -2.3 0.92 0.00 0.00 0.00 2010.0
172 // rates 0.3 0.0 -0.1 0.03 0.00 0.00 0.00
173 // ITRF2000 0.7 1.2 -26.1 2.12 0.00 0.00 0.00 2010.0
174 // rates 0.1 0.1 -1.9 0.11 0.00 0.00 0.00
175 // ITRF97 7.4 -0.5 -62.8 3.80 0.00 0.00 0.26 2010.0
176 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
177 // ITRF96 7.4 -0.5 -62.8 3.80 0.00 0.00 0.26 2010.0
178 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
179 // ITRF94 7.4 -0.5 -62.8 3.80 0.00 0.00 0.26 2010.0
180 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
181 // ITRF93 -50.4 3.3 -60.2 4.29 -2.81 -3.38 0.40 2010.0
182 // rates -2.8 -0.1 -2.5 0.12 -0.11 -0.19 0.07
183 // ITRF92 15.4 1.5 -70.8 3.09 0.00 0.00 0.26 2010.0
184 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
185 // ITRF91 27.4 15.5 -76.8 4.49 0.00 0.00 0.26 2010.0
186 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
187 // ITRF90 25.4 11.5 -92.8 4.79 0.00 0.00 0.26 2010.0
188 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
189 // ITRF89 30.4 35.5 -130.8 8.19 0.00 0.00 0.26 2010.0
190 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
191 // ITRF88 25.4 -0.5 -154.8 11.29 0.10 0.00 0.26 2010.0
192 // rates 0.1 -0.5 -3.3 0.12 0.00 0.00 0.02
193 // _________________________________________________________________________________________
194
195 /** Transformation from ITRF 2014 To ITRF 2008. */
196 ITRF_2014_TO_ITRF_2008(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_2008, 2010,
197 1.6, 1.9, 2.4, 0.00, 0.00, 0.00,
198 0.0, 0.0, -0.1, 0.00, 0.00, 0.00),
199
200 /** Transformation from ITRF 2014 To ITRF 2005. */
201 ITRF_2014_TO_ITRF_2005(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_2005, 2010,
202 2.6, 1.0, -2.3, 0.00, 0.00, 0.00,
203 0.3, 0.0, -0.1, 0.00, 0.00, 0.00),
204
205 /** Transformation from ITRF 2014 To ITRF 2000. */
206 ITRF_2014_TO_ITRF_2000(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_2000, 2010,
207 0.7, 1.2, -26.1, 0.00, 0.00, 0.00,
208 0.1, 0.1, -1.9, 0.00, 0.00, 0.00),
209
210 /** Transformation from ITRF 2014 To ITRF 97. */
211 ITRF_2014_TO_ITRF_1997(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1997, 2010,
212 7.4, -0.5, -62.8, 0.00, 0.00, 0.26,
213 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
214
215 /** Transformation from ITRF 2014 To ITRF 96. */
216 ITRF_2014_TO_ITRF_1996(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1996, 2010,
217 7.4, -0.5, -62.8, 0.00, 0.00, 0.26,
218 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
219
220 /** Transformation from ITRF 2014 To ITRF 94. */
221 ITRF_2014_TO_ITRF_1994(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1994, 2010,
222 7.4, -0.5, -62.8, 0.00, 0.00, 0.26,
223 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
224
225 /** Transformation from ITRF 2014 To ITRF 93. */
226 ITRF_2014_TO_ITRF_1993(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1993, 2010,
227 -50.4, 3.3, -60.2, -2.81, -3.38, 0.40,
228 -2.8, -0.1, -2.5, -0.11, -0.19, 0.07),
229
230 /** Transformation from ITRF 2014 To ITRF 92. */
231 ITRF_2014_TO_ITRF_1992(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1992, 2010,
232 15.4, 1.5, -70.8, 0.00, 0.00, 0.26,
233 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
234
235 /** Transformation from ITRF 2014 To ITRF 91. */
236 ITRF_2014_TO_ITRF_1991(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1991, 2010,
237 27.4, 15.5, -76.8, 0.00, 0.00, 0.26,
238 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
239
240 /** Transformation from ITRF 2014 To ITRF 90. */
241 ITRF_2014_TO_ITRF_1990(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1990, 2010,
242 25.4, 11.5, -92.8, 0.00, 0.00, 0.26,
243 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
244
245 /** Transformation from ITRF 2014 To ITRF 89. */
246 ITRF_2014_TO_ITRF_1989(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1989, 2010,
247 30.4, 35.5, -130.8, 0.00, 0.00, 0.26,
248 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
249
250 /** Transformation from ITRF 2014 To ITRF 88. */
251 ITRF_2014_TO_ITRF_1988(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1988, 2010,
252 25.4, -0.5, -154.8, 0.10, 0.00, 0.26,
253 0.1, -0.5, -3.3, 0.00, 0.00, 0.02),
254
255 // see http://itrf.ensg.ign.fr/doc_ITRF/Transfo-ITRF2008_ITRFs.txt
256 // SOLUTION Tx Ty Tz D Rx Ry Rz EPOCH
257 // UNITS----------> mm mm mm ppb .001" .001" .001"
258 // . . . . . . .
259 // RATES Tx Ty Tz D Rx Ry Rz
260 // UNITS----------> mm/y mm/y mm/y ppb/y .001"/y .001"/y .001"/y
261 // -----------------------------------------------------------------------------------------
262 // ITRF2005 -2.0 -0.9 -4.7 0.94 0.00 0.00 0.00 2000.0
263 // rates 0.3 0.0 0.0 0.00 0.00 0.00 0.00
264 // ITRF2000 -1.9 -1.7 -10.5 1.34 0.00 0.00 0.00 2000.0
265 // rates 0.1 0.1 -1.8 0.08 0.00 0.00 0.00
266 // ITRF97 4.8 2.6 -33.2 2.92 0.00 0.00 0.06 2000.0
267 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
268 // ITRF96 4.8 2.6 -33.2 2.92 0.00 0.00 0.06 2000.0
269 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
270 // ITRF94 4.8 2.6 -33.2 2.92 0.00 0.00 0.06 2000.0
271 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
272 // ITRF93 -24.0 2.4 -38.6 3.41 -1.71 -1.48 -0.30 2000.0
273 // rates -2.8 -0.1 -2.4 0.09 -0.11 -0.19 0.07
274 // ITRF92 12.8 4.6 -41.2 2.21 0.00 0.00 0.06 2000.0
275 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
276 // ITRF91 24.8 18.6 -47.2 3.61 0.00 0.00 0.06 2000.0
277 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
278 // ITRF90 22.8 14.6 -63.2 3.91 0.00 0.00 0.06 2000.0
279 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
280 // ITRF89 27.8 38.6 -101.2 7.31 0.00 0.00 0.06 2000.0
281 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
282 // ITRF88 22.8 2.6 -125.2 10.41 0.10 0.00 0.06 2000.0
283 // rates 0.1 -0.5 -3.2 0.09 0.00 0.00 0.02
284 // _________________________________________________________________________________________
285
286 /** Transformation from ITRF 2008 To ITRF 2005. */
287 ITRF_2008_TO_ITRF_2005(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_2005, 2000,
288 -2.0, -0.9, -4.7, 0.00, 0.00, 0.00,
289 0.3, 0.0, 0.0, 0.00, 0.00, 0.00),
290
291 /** Transformation from ITRF 2008 To ITRF 2000. */
292 ITRF_2008_TO_ITRF_2000(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_2000, 2000,
293 -1.9, -1.7, -10.5, 0.00, 0.00, 0.00,
294 0.1, 0.1, -1.8, 0.00, 0.00, 0.00),
295
296 /** Transformation from ITRF 2008 To ITRF 97. */
297 ITRF_2008_TO_ITRF_1997(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1997, 2000,
298 4.8, 2.6, -33.2, 0.00, 0.00, 0.06,
299 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
300
301 /** Transformation from ITRF 2008 To ITRF 96. */
302 ITRF_2008_TO_ITRF_1996(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1996, 2000,
303 4.8, 2.6, -33.2, 0.00, 0.00, 0.06,
304 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
305
306 /** Transformation from ITRF 2008 To ITRF 94. */
307 ITRF_2008_TO_ITRF_1994(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1994, 2000,
308 4.8, 2.6, -33.2, 0.00, 0.00, 0.06,
309 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
310
311 /** Transformation from ITRF 2008 To ITRF 93. */
312 ITRF_2008_TO_ITRF_1993(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1993, 2000,
313 -24.0, 2.4, -38.6, -1.71, -1.48, -0.30,
314 -2.8, -0.1, -2.4, -0.11, -0.19, 0.07),
315
316 /** Transformation from ITRF 2008 To ITRF 92. */
317 ITRF_2008_TO_ITRF_1992(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1992, 2000,
318 12.8, 4.6, -41.2, 0.00, 0.00, 0.06,
319 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
320
321 /** Transformation from ITRF 2008 To ITRF 91. */
322 ITRF_2008_TO_ITRF_1991(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1991, 2000,
323 24.8, 18.6, -47.2, 0.00, 0.00, 0.06,
324 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
325
326 /** Transformation from ITRF 2008 To ITRF 90. */
327 ITRF_2008_TO_ITRF_1990(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1990, 2000,
328 22.8, 14.6, -63.2, 0.00, 0.00, 0.06,
329 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
330
331 /** Transformation from ITRF 2008 To ITRF 89. */
332 ITRF_2008_TO_ITRF_1989(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1989, 2000,
333 27.8, 38.6, -101.2, 0.00, 0.00, 0.06,
334 0.1, -0.5, -3.2, 0.00, 0.00, 0.02),
335
336 /** Transformation from ITRF 2008 To ITRF 88. */
337 ITRF_2008_TO_ITRF_1988(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1988, 2000,
338 22.8, 2.6, -125.2, 0.10, 0.00, 0.06,
339 0.1, -0.5, -3.2, 0.00, 0.00, 0.02);
340
341 /** Origin ITRF. */
342 private final ITRFVersion origin;
343
344 /** Destination ITRF. */
345 private final ITRFVersion destination;
346
347 /** Transformation. */
348 private final transient HelmertTransformationWithoutTimeScale transformation;
349
350 /** Simple constructor.
351 * @param origin origin ITRF
352 * @param destination destination ITRF
353 * @param refYear reference year for the epoch of the transform
354 * @param t1 translation parameter along X axis (BEWARE, this is in mm)
355 * @param t2 translation parameter along Y axis (BEWARE, this is in mm)
356 * @param t3 translation parameter along Z axis (BEWARE, this is in mm)
357 * @param r1 rotation parameter around X axis (BEWARE, this is in mas)
358 * @param r2 rotation parameter around Y axis (BEWARE, this is in mas)
359 * @param r3 rotation parameter around Z axis (BEWARE, this is in mas)
360 * @param t1Dot rate of translation parameter along X axis (BEWARE, this is in mm/y)
361 * @param t2Dot rate of translation parameter along Y axis (BEWARE, this is in mm/y)
362 * @param t3Dot rate of translation parameter along Z axis (BEWARE, this is in mm/y)
363 * @param r1Dot rate of rotation parameter around X axis (BEWARE, this is in mas/y)
364 * @param r2Dot rate of rotation parameter around Y axis (BEWARE, this is in mas/y)
365 * @param r3Dot rate of rotation parameter around Z axis (BEWARE, this is in mas/y)
366 */
367 Predefined(final ITRFVersion origin, final ITRFVersion destination, final int refYear,
368 final double t1, final double t2, final double t3,
369 final double r1, final double r2, final double r3,
370 final double t1Dot, final double t2Dot, final double t3Dot,
371 final double r1Dot, final double r2Dot, final double r3Dot) {
372 this.origin = origin;
373 this.destination = destination;
374 this.transformation =
375 new HelmertTransformationWithoutTimeScale(new DateTimeComponents(refYear, 1, 1, 12, 0, 0),
376 t1, t2, t3, r1, r2, r3, t1Dot, t2Dot, t3Dot, r1Dot, r2Dot, r3Dot);
377 }
378
379 /** Get the origin ITRF.
380 * @return origin ITRF
381 * @since 9.2
382 */
383 public ITRFVersion getOrigin() {
384 return origin;
385 }
386
387 /** Get the destination ITRF.
388 * @return destination ITRF
389 * @since 9.2
390 */
391 public ITRFVersion getDestination() {
392 return destination;
393 }
394
395 /** Get the underlying {@link HelmertTransformation}.
396 *
397 * <p>This method uses the {@link DataContext#getDefault() default data context}.
398 *
399 * @return underlying {@link HelmertTransformation}
400 * @since 9.2
401 * @see #getTransformation(TimeScale)
402 */
403 @DefaultDataContext
404 public HelmertTransformation getTransformation() {
405 return getTransformation(DataContext.getDefault().getTimeScales().getTT());
406 }
407
408 /** Get the underlying {@link HelmertTransformation}.
409 * @return underlying {@link HelmertTransformation}
410 * @param tt TT time scale.
411 * @since 10.1
412 */
413 public HelmertTransformation getTransformation(final TimeScale tt) {
414 return transformation.withTimeScale(tt);
415 }
416
417 /** Create an ITRF frame by transforming another ITRF frame.
418 *
419 * <p>This method uses the {@link DataContext#getDefault() default data context}.
420 *
421 * @param parent parent ITRF frame
422 * @param name name of the frame to create
423 * @return new ITRF frame
424 * @see #createTransformedITRF(Frame, String, TimeScale)
425 */
426 @DefaultDataContext
427 public Frame createTransformedITRF(final Frame parent, final String name) {
428 return createTransformedITRF(parent, name,
429 DataContext.getDefault().getTimeScales().getTT());
430 }
431
432 /** Create an ITRF frame by transforming another ITRF frame.
433 * @param parent parent ITRF frame
434 * @param name name of the frame to create
435 * @param tt TT time scale.
436 * @return new ITRF frame
437 * @since 10.1
438 */
439 public Frame createTransformedITRF(final Frame parent,
440 final String name,
441 final TimeScale tt) {
442 return new Frame(parent, getTransformation(tt), name);
443 }
444
445 /** Select a predefined transform between two years.
446 * @param origin origin year
447 * @param destination destination year
448 * @return predefined transform from origin to destination, or null if no such predefined transform exist
449 * @since 11.2
450 */
451 public static Predefined selectPredefined(final int origin, final int destination) {
452 final Optional<HelmertTransformation.Predefined> optional =
453 Stream.
454 of(HelmertTransformation.Predefined.values()).
455 filter(p -> p.getOrigin().getYear() == origin && p.getDestination().getYear() == destination).
456 findFirst();
457 return optional.isPresent() ? optional.get() : null;
458 }
459
460 }
461
462 /**
463 * A {@link HelmertTransformation} without reference to a {@link TimeScale}. This
464 * class is needed to maintain compatibility with Orekit 10.0 since {@link Predefined}
465 * is an enum and it had a reference to the TT time scale.
466 */
467 private static class HelmertTransformationWithoutTimeScale {
468
469 /** Cartesian part of the transform. */
470 private final PVCoordinates cartesian;
471
472 /** Global rotation vector (applying rotation is done by computing cross product). */
473 private final Vector3D rotationVector;
474
475 /** First time derivative of the rotation (norm representing angular rate). */
476 private final Vector3D rotationRate;
477
478 /** Reference epoch of the transform. */
479 private final DateTimeComponents epoch;
480
481 /** Build a transform from its primitive operations.
482 * @param epoch reference epoch of the transform
483 * @param t1 translation parameter along X axis (BEWARE, this is in mm)
484 * @param t2 translation parameter along Y axis (BEWARE, this is in mm)
485 * @param t3 translation parameter along Z axis (BEWARE, this is in mm)
486 * @param r1 rotation parameter around X axis (BEWARE, this is in mas)
487 * @param r2 rotation parameter around Y axis (BEWARE, this is in mas)
488 * @param r3 rotation parameter around Z axis (BEWARE, this is in mas)
489 * @param t1Dot rate of translation parameter along X axis (BEWARE, this is in mm/y)
490 * @param t2Dot rate of translation parameter along Y axis (BEWARE, this is in mm/y)
491 * @param t3Dot rate of translation parameter along Z axis (BEWARE, this is in mm/y)
492 * @param r1Dot rate of rotation parameter around X axis (BEWARE, this is in mas/y)
493 * @param r2Dot rate of rotation parameter around Y axis (BEWARE, this is in mas/y)
494 * @param r3Dot rate of rotation parameter around Z axis (BEWARE, this is in mas/y)
495 */
496 HelmertTransformationWithoutTimeScale(
497 final DateTimeComponents epoch,
498 final double t1, final double t2, final double t3,
499 final double r1, final double r2, final double r3,
500 final double t1Dot, final double t2Dot, final double t3Dot,
501 final double r1Dot, final double r2Dot, final double r3Dot) {
502
503 // conversion parameters to SI units
504 final double mmToM = 1.0e-3;
505 final double masToRad = 1.0e-3 * Constants.ARC_SECONDS_TO_RADIANS;
506
507 this.epoch = epoch;
508 this.cartesian = new PVCoordinates(new Vector3D(t1 * mmToM,
509 t2 * mmToM,
510 t3 * mmToM),
511 new Vector3D(t1Dot * mmToM / Constants.JULIAN_YEAR,
512 t2Dot * mmToM / Constants.JULIAN_YEAR,
513 t3Dot * mmToM / Constants.JULIAN_YEAR));
514 this.rotationVector = new Vector3D(r1 * masToRad,
515 r2 * masToRad,
516 r3 * masToRad);
517 this.rotationRate = new Vector3D(r1Dot * masToRad / Constants.JULIAN_YEAR,
518 r2Dot * masToRad / Constants.JULIAN_YEAR,
519 r3Dot * masToRad / Constants.JULIAN_YEAR);
520
521 }
522
523 /**
524 * Get the Helmert transformation with reference to the given time scale.
525 *
526 * @param tt TT time scale.
527 * @return Helmert transformation.
528 */
529 public HelmertTransformation withTimeScale(final TimeScale tt) {
530 return new HelmertTransformation(cartesian, rotationVector, rotationRate,
531 new AbsoluteDate(epoch, tt));
532 }
533
534 }
535
536 /** Cartesian part of the transform. */
537 private final PVCoordinates cartesian;
538
539 /** Global rotation vector (applying rotation is done by computing cross product). */
540 private final Vector3D rotationVector;
541
542 /** First time derivative of the rotation (norm representing angular rate). */
543 private final Vector3D rotationRate;
544
545 /** Reference epoch of the transform. */
546 private final AbsoluteDate epoch;
547
548 /** Build a transform from its primitive operations.
549 * @param epoch reference epoch of the transform
550 * @param t1 translation parameter along X axis (BEWARE, this is in mm)
551 * @param t2 translation parameter along Y axis (BEWARE, this is in mm)
552 * @param t3 translation parameter along Z axis (BEWARE, this is in mm)
553 * @param r1 rotation parameter around X axis (BEWARE, this is in mas)
554 * @param r2 rotation parameter around Y axis (BEWARE, this is in mas)
555 * @param r3 rotation parameter around Z axis (BEWARE, this is in mas)
556 * @param t1Dot rate of translation parameter along X axis (BEWARE, this is in mm/y)
557 * @param t2Dot rate of translation parameter along Y axis (BEWARE, this is in mm/y)
558 * @param t3Dot rate of translation parameter along Z axis (BEWARE, this is in mm/y)
559 * @param r1Dot rate of rotation parameter around X axis (BEWARE, this is in mas/y)
560 * @param r2Dot rate of rotation parameter around Y axis (BEWARE, this is in mas/y)
561 * @param r3Dot rate of rotation parameter around Z axis (BEWARE, this is in mas/y)
562 */
563 public HelmertTransformation(final AbsoluteDate epoch,
564 final double t1, final double t2, final double t3,
565 final double r1, final double r2, final double r3,
566 final double t1Dot, final double t2Dot, final double t3Dot,
567 final double r1Dot, final double r2Dot, final double r3Dot) {
568
569 // conversion parameters to SI units
570 final double mmToM = 1.0e-3;
571 final double masToRad = 1.0e-3 * Constants.ARC_SECONDS_TO_RADIANS;
572
573 this.epoch = epoch;
574 this.cartesian = new PVCoordinates(new Vector3D(t1 * mmToM,
575 t2 * mmToM,
576 t3 * mmToM),
577 new Vector3D(t1Dot * mmToM / Constants.JULIAN_YEAR,
578 t2Dot * mmToM / Constants.JULIAN_YEAR,
579 t3Dot * mmToM / Constants.JULIAN_YEAR));
580 this.rotationVector = new Vector3D(r1 * masToRad,
581 r2 * masToRad,
582 r3 * masToRad);
583 this.rotationRate = new Vector3D(r1Dot * masToRad / Constants.JULIAN_YEAR,
584 r2Dot * masToRad / Constants.JULIAN_YEAR,
585 r3Dot * masToRad / Constants.JULIAN_YEAR);
586
587 }
588
589 /**
590 * Private constructor.
591 *
592 * @param cartesian part of the transform.
593 * @param rotationVector global rotation vector.
594 * @param rotationRate time derivative of rotation.
595 * @param epoch of transform.
596 */
597 private HelmertTransformation(final PVCoordinates cartesian,
598 final Vector3D rotationVector,
599 final Vector3D rotationRate,
600 final AbsoluteDate epoch) {
601 this.cartesian = cartesian;
602 this.rotationVector = rotationVector;
603 this.rotationRate = rotationRate;
604 this.epoch = epoch;
605 }
606
607 /** Get the reference epoch of the transform.
608 * @return reference epoch of the transform
609 */
610 public AbsoluteDate getEpoch() {
611 return epoch;
612 }
613
614 /** {@inheritDoc} */
615 @Override
616 public Transform getTransform(final AbsoluteDate date) {
617
618 // compute parameters evolution since reference epoch
619 final double dt = date.durationFrom(epoch);
620 final Vector3D dR = new Vector3D(1, rotationVector, dt, rotationRate);
621
622 // build translation part
623 final Transform translationTransform = new Transform(date, cartesian.shiftedBy(dt));
624
625 // build rotation part
626 final double angle = dR.getNorm();
627 final Transform rotationTransform =
628 new Transform(date,
629 (angle < Precision.SAFE_MIN) ?
630 Rotation.IDENTITY :
631 new Rotation(dR, angle, RotationConvention.VECTOR_OPERATOR),
632 rotationRate);
633
634 // combine both parts
635 return new Transform(date, translationTransform, rotationTransform);
636
637 }
638
639 /** {@inheritDoc} */
640 @Override
641 public StaticTransform getStaticTransform(final AbsoluteDate date) {
642
643 // compute parameters evolution since reference epoch
644 final double dt = date.durationFrom(epoch);
645 final Vector3D dR = new Vector3D(1, rotationVector, dt, rotationRate);
646
647 // build translation part
648 final Vector3D translation = cartesian.shiftedBy(dt).getPosition();
649
650 // build rotation part
651 final double angle = dR.getNorm();
652 final Rotation rotation = (angle < Precision.SAFE_MIN) ?
653 Rotation.IDENTITY :
654 new Rotation(dR, angle, RotationConvention.VECTOR_OPERATOR);
655
656 // combine both parts
657 return StaticTransform.of(date, translation, rotation);
658
659 }
660
661 /** {@inheritDoc} */
662 @Override
663 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
664
665 // compute parameters evolution since reference epoch
666 final T dt = date.durationFrom(epoch);
667 final FieldVector3D<T> dR = new FieldVector3D<>(date.getField().getOne(), rotationVector,
668 dt, rotationRate);
669
670 // build translation part
671 final FieldTransform<T> translationTransform =
672 new FieldTransform<>(date,
673 new FieldPVCoordinates<>(date.getField(), cartesian).shiftedBy(dt));
674
675 // build rotation part
676 final T angle = dR.getNorm();
677 final FieldTransform<T> rotationTransform =
678 new FieldTransform<>(date,
679 (angle.getReal() < Precision.SAFE_MIN) ?
680 FieldRotation.getIdentity(date.getField()) :
681 new FieldRotation<>(dR, angle, RotationConvention.VECTOR_OPERATOR),
682 new FieldVector3D<>(date.getField(), rotationRate));
683
684 // combine both parts
685 return new FieldTransform<>(date, translationTransform, rotationTransform);
686
687 }
688
689 /** {@inheritDoc} */
690 @Override
691 public <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {
692
693 // field
694 final Field<T> field = date.getField();
695
696 // compute parameters evolution since reference epoch
697 final T dt = date.durationFrom(epoch);
698 final FieldVector3D<T> dR = new FieldVector3D<>(field.getOne(), rotationVector, dt, rotationRate);
699
700 // build translation part
701 final FieldVector3D<T> translation = new FieldPVCoordinates<>(date.getField(), cartesian).shiftedBy(dt).getPosition();
702
703 // build rotation part
704 final T angle = dR.getNorm();
705 final FieldRotation<T> rotation = (angle.getReal() < Precision.SAFE_MIN) ?
706 FieldRotation.getIdentity(field) :
707 new FieldRotation<>(dR, angle, RotationConvention.VECTOR_OPERATOR);
708
709 // combine both parts
710 return FieldStaticTransform.of(date, translation, rotation);
711
712 }
713
714 }