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 }