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