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 }