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