HelmertTransformation.java

  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. import java.util.Optional;
  19. import java.util.stream.Stream;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.hipparchus.Field;
  22. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  23. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  24. import org.hipparchus.geometry.euclidean.threed.Rotation;
  25. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  26. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  27. import org.hipparchus.util.Precision;
  28. import org.orekit.annotation.DefaultDataContext;
  29. import org.orekit.data.DataContext;
  30. import org.orekit.time.AbsoluteDate;
  31. import org.orekit.time.DateTimeComponents;
  32. import org.orekit.time.FieldAbsoluteDate;
  33. import org.orekit.time.TimeScale;
  34. import org.orekit.utils.Constants;
  35. import org.orekit.utils.FieldPVCoordinates;
  36. import org.orekit.utils.PVCoordinates;


  37. /** Transformation class for geodetic systems.
  38.  *
  39.  * <p>The Helmert transformation is mainly used to convert between various
  40.  * realizations of geodetic frames, for example in the ITRF family.</p>
  41.  *
  42.  * <p>The original Helmert transformation is a 14 parameters transform that
  43.  * includes translation, velocity, rotation, rotation rate and scale factor.
  44.  * The scale factor is useful for coordinates near Earth surface, but it
  45.  * cannot be extended to outer space as it would correspond to a non-unitary
  46.  * transform. Therefore, the scale factor is <em>not</em> used here.
  47.  *
  48.  * <p>Instances of this class are guaranteed to be immutable.</p>
  49.  *
  50.  * @author Luc Maisonobe
  51.  * @since 5.1
  52.  */
  53. public class HelmertTransformation implements TransformProvider {

  54.     /** serializable UID. */
  55.     private static final long serialVersionUID = 20220419L;

  56.     /** Enumerate for predefined Helmert transformations. */
  57.     public enum Predefined {

  58.         // see https://itrf.ign.fr/docs/solutions/itrf2020/Transfo-ITRF2020_TRFs.txt
  59.         // SOLUTION         Tx       Ty       Tz        D        Rx        Ry        Rz      EPOCH
  60.         // UNITS----------> mm       mm       mm       ppb       .001"     .001"     .001"
  61.         //                  .        .        .         .        .         .         .
  62.         //        RATES     Tx       Ty       Tz        D        Rx        Ry        Rz
  63.         // UNITS----------> mm/y     mm/y     mm/y     ppb/y    .001"/y   .001"/y   .001"/y
  64.         // -----------------------------------------------------------------------------------------
  65.         //   ITRF2014       -1.4     -0.9      1.4     -0.42      0.00      0.00      0.00    2015.0
  66.         //        rates      0.0     -0.1      0.2      0.00      0.00      0.00      0.00
  67.         //   ITRF2008        0.2      1.0      3.3     -0.29      0.00      0.00      0.00    2015.0
  68.         //        rates      0.0     -0.1      0.1      0.03      0.00      0.00      0.00
  69.         //   ITRF2005        2.7      0.1     -1.4      0.65      0.00      0.00      0.00    2015.0
  70.         //        rates      0.3     -0.1      0.1      0.03      0.00      0.00      0.00
  71.         //   ITRF2000       -0.2      0.8    -34.2      2.25      0.00      0.00      0.00    2015.0
  72.         //        rates      0.1      0.0     -1.7      0.11      0.00      0.00      0.00
  73.         //   ITRF97          6.5     -3.9    -77.9      3.98      0.00      0.00      0.36    2015.0
  74.         //        rates      0.1     -0.6     -3.1      0.12      0.00      0.00      0.02
  75.         //   ITRF96          6.5     -3.9    -77.9      3.98      0.00      0.00      0.36    2015.0
  76.         //        rates      0.1     -0.6     -3.1      0.12      0.00      0.00      0.02
  77.         //   ITRF94          6.5     -3.9    -77.9      3.98      0.00      0.00      0.36    2015.0
  78.         //        rates      0.1     -0.6     -3.1      0.12      0.00      0.00      0.02
  79.         //   ITRF93        -65.8      1.9    -71.3      4.47     -3.36     -4.33      0.75    2015.0
  80.         //        rates     -2.8     -0.2     -2.3      0.12     -0.11     -0.19      0.07
  81.         //   ITRF92         14.5     -1.9    -85.9      3.27      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.         //   ITRF91         26.5     12.1    -91.9      4.67      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.         //   ITRF90         24.5      8.1   -107.9      4.97      0.00      0.00      0.36    2015.0
  86.         //        rates      0.1     -0.6     -3.1      0.12      0.00      0.00      0.02
  87.         //   ITRF89         29.5     32.1   -145.9      8.37      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.         //   ITRF88         24.5     -3.9   -169.9     11.47      0.10      0.00      0.36    2015.0
  90.         //        rates      0.1     -0.6     -3.1      0.12      0.00      0.00      0.02
  91.         // _________________________________________________________________________________________

  92.         /** Transformation from ITRF 2020 To ITRF 2014. */
  93.         ITRF_2020_TO_ITRF_2014(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2014, 2015,
  94.                                -1.4, -0.9,   1.4,  0.00,  0.00,  0.00,
  95.                                 0.0, -0.1,   0.2,  0.00,  0.00,  0.00),

  96.         /** Transformation from ITRF 2020 To ITRF 2008. */
  97.         ITRF_2020_TO_ITRF_2008(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2008, 2015,
  98.                                0.2,  1.0,   3.3,  0.00,  0.00,  0.00,
  99.                                0.0, -0.1,   0.1,  0.00,  0.00,  0.00),

  100.         /** Transformation from ITRF 2020 To ITRF 2005. */
  101.         ITRF_2020_TO_ITRF_2005(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2005, 2015,
  102.                                2.7,  0.1,  -1.4,  0.00,  0.00,  0.00,
  103.                                0.3, -0.1,   0.1,  0.00,  0.00,  0.00),

  104.         /** Transformation from ITRF 2020 To ITRF 2000. */
  105.         ITRF_2020_TO_ITRF_2000(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_2000, 2015,
  106.                                -0.2,  0.8, -34.2,  0.00,  0.00,  0.00,
  107.                                 0.1,  0.0,  -1.7,  0.00,  0.00,  0.00),

  108.         /** Transformation from ITRF 2020 To ITRF 97. */
  109.         ITRF_2020_TO_ITRF_1997(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1997, 2015,
  110.                                6.5, -3.9, -77.9,  0.00,  0.00,  0.36,
  111.                                0.1, -0.6,  -3.1,  0.00,  0.00,  0.02),

  112.         /** Transformation from ITRF 2020 To ITRF 96. */
  113.         ITRF_2020_TO_ITRF_1996(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1996, 2015,
  114.                                6.5, -3.9, -77.9,  0.00,  0.00,  0.36,
  115.                                0.1, -0.6,  -3.1,  0.00,  0.00,  0.02),

  116.         /** Transformation from ITRF 2020 To ITRF 94. */
  117.         ITRF_2020_TO_ITRF_1994(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1994, 2015,
  118.                                6.5, -3.9, -77.9,  0.00,  0.00,  0.36,
  119.                                0.1, -0.6,  -3.1,  0.00,  0.00,  0.02),

  120.         /** Transformation from ITRF 2020 To ITRF 93. */
  121.         ITRF_2020_TO_ITRF_1993(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1993, 2015,
  122.                                -65.8,  1.9, -71.3, -3.36, -4.33,  0.75,
  123.                                 -2.8, -0.2,  -2.3, -0.11, -0.19,  0.07),

  124.         /** Transformation from ITRF 2020 To ITRF 92. */
  125.         ITRF_2020_TO_ITRF_1992(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1992, 2015,
  126.                                14.5, -1.9, -85.9,  0.00,  0.00,  0.36,
  127.                                 0.1, -0.6,  -3.1,  0.00,  0.00,  0.02),

  128.         /** Transformation from ITRF 2020 To ITRF 91. */
  129.         ITRF_2020_TO_ITRF_1991(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1991, 2015,
  130.                                26.5, 12.1, -91.9,  0.00,  0.00,  0.36,
  131.                                 0.1, -0.6,  -3.1,  0.00,  0.00,  0.02),

  132.         /** Transformation from ITRF 2020 To ITRF 90. */
  133.         ITRF_2020_TO_ITRF_1990(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1990, 2015,
  134.                                24.5,  8.1, -107.9,  0.00,  0.00,  0.36,
  135.                                 0.1, -0.6,   -3.1,  0.00,  0.00,  0.02),

  136.         /** Transformation from ITRF 2020 To ITRF 89. */
  137.         ITRF_2020_TO_ITRF_1989(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1989, 2015,
  138.                                29.5, 32.1, -145.9,  0.00,  0.00,  0.36,
  139.                                 0.1, -0.6,   -3.1,  0.00,  0.00,  0.02),

  140.         /** Transformation from ITRF 2020 To ITRF 88. */
  141.         ITRF_2020_TO_ITRF_1988(ITRFVersion.ITRF_2020, ITRFVersion.ITRF_1988, 2015,
  142.                                24.5, -3.9, -169.9,  0.10,  0.00,  0.36,
  143.                                 0.1, -0.6,   -3.1,  0.00,  0.00,  0.02),

  144.         // see http://itrf.ign.fr/doc_ITRF/Transfo-ITRF2014_ITRFs.txt
  145.         // SOLUTION         Tx       Ty       Tz        D        Rx        Ry        Rz      EPOCH
  146.         // UNITS----------> mm       mm       mm       ppb       .001"     .001"     .001"
  147.         //                  .        .        .         .        .         .         .
  148.         //        RATES     Tx       Ty       Tz        D        Rx        Ry        Rz
  149.         // UNITS----------> mm/y     mm/y     mm/y     ppb/y    .001"/y   .001"/y   .001"/y
  150.         // -----------------------------------------------------------------------------------------
  151.         //   ITRF2008        1.6      1.9      2.4     -0.02      0.00      0.00      0.00    2010.0
  152.         //        rates      0.0      0.0     -0.1      0.03      0.00      0.00      0.00
  153.         //   ITRF2005        2.6      1.0     -2.3      0.92      0.00      0.00      0.00    2010.0
  154.         //        rates      0.3      0.0     -0.1      0.03      0.00      0.00      0.00
  155.         //   ITRF2000        0.7      1.2    -26.1      2.12      0.00      0.00      0.00    2010.0
  156.         //        rates      0.1      0.1     -1.9      0.11      0.00      0.00      0.00
  157.         //   ITRF97          7.4     -0.5    -62.8      3.80      0.00      0.00      0.26    2010.0
  158.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  159.         //   ITRF96          7.4     -0.5    -62.8      3.80      0.00      0.00      0.26    2010.0
  160.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  161.         //   ITRF94          7.4     -0.5    -62.8      3.80      0.00      0.00      0.26    2010.0
  162.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  163.         //   ITRF93        -50.4      3.3    -60.2      4.29     -2.81     -3.38      0.40    2010.0
  164.         //        rates     -2.8     -0.1     -2.5      0.12     -0.11     -0.19      0.07
  165.         //   ITRF92         15.4      1.5    -70.8      3.09      0.00      0.00      0.26    2010.0
  166.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  167.         //   ITRF91         27.4     15.5    -76.8      4.49      0.00      0.00      0.26    2010.0
  168.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  169.         //   ITRF90         25.4     11.5    -92.8      4.79      0.00      0.00      0.26    2010.0
  170.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  171.         //   ITRF89         30.4     35.5   -130.8      8.19      0.00      0.00      0.26    2010.0
  172.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  173.         //   ITRF88         25.4     -0.5   -154.8     11.29      0.10      0.00      0.26    2010.0
  174.         //        rates      0.1     -0.5     -3.3      0.12      0.00      0.00      0.02
  175.         // _________________________________________________________________________________________

  176.         /** Transformation from ITRF 2014 To ITRF 2008. */
  177.         ITRF_2014_TO_ITRF_2008(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_2008, 2010,
  178.                                 1.6, 1.9,     2.4, 0.00, 0.00, 0.00,
  179.                                 0.0, 0.0,    -0.1, 0.00, 0.00, 0.00),

  180.         /** Transformation from ITRF 2014 To ITRF 2005. */
  181.         ITRF_2014_TO_ITRF_2005(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_2005, 2010,
  182.                                 2.6, 1.0,    -2.3, 0.00, 0.00, 0.00,
  183.                                 0.3, 0.0,    -0.1, 0.00, 0.00, 0.00),

  184.         /** Transformation from ITRF 2014 To ITRF 2000. */
  185.         ITRF_2014_TO_ITRF_2000(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_2000, 2010,
  186.                                0.7, 1.2,   -26.1, 0.00, 0.00, 0.00,
  187.                                0.1, 0.1,    -1.9, 0.00, 0.00, 0.00),

  188.         /** Transformation from ITRF 2014 To ITRF 97. */
  189.         ITRF_2014_TO_ITRF_1997(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1997, 2010,
  190.                                7.4, -0.5,  -62.8, 0.00, 0.00, 0.26,
  191.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  192.         /** Transformation from ITRF 2014 To ITRF 96. */
  193.         ITRF_2014_TO_ITRF_1996(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1996, 2010,
  194.                                7.4, -0.5,  -62.8, 0.00, 0.00, 0.26,
  195.                                0.1, -0.5,  -3.3, 0.00, 0.00, 0.02),

  196.         /** Transformation from ITRF 2014 To ITRF 94. */
  197.         ITRF_2014_TO_ITRF_1994(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1994, 2010,
  198.                                7.4, -0.5,  -62.8, 0.00, 0.00, 0.26,
  199.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  200.         /** Transformation from ITRF 2014 To ITRF 93. */
  201.         ITRF_2014_TO_ITRF_1993(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1993, 2010,
  202.                                -50.4,  3.3,  -60.2, -2.81, -3.38, 0.40,
  203.                                -2.8, -0.1,   -2.5, -0.11, -0.19, 0.07),

  204.         /** Transformation from ITRF 2014 To ITRF 92. */
  205.         ITRF_2014_TO_ITRF_1992(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1992, 2010,
  206.                                15.4,  1.5,  -70.8, 0.00, 0.00, 0.26,
  207.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  208.         /** Transformation from ITRF 2014 To ITRF 91. */
  209.         ITRF_2014_TO_ITRF_1991(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1991, 2010,
  210.                                27.4, 15.5,  -76.8, 0.00, 0.00, 0.26,
  211.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  212.         /** Transformation from ITRF 2014 To ITRF 90. */
  213.         ITRF_2014_TO_ITRF_1990(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1990, 2010,
  214.                                25.4, 11.5,  -92.8, 0.00, 0.00, 0.26,
  215.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  216.         /** Transformation from ITRF 2014 To ITRF 89. */
  217.         ITRF_2014_TO_ITRF_1989(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1989, 2010,
  218.                                30.4, 35.5, -130.8, 0.00, 0.00, 0.26,
  219.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  220.         /** Transformation from ITRF 2014 To ITRF 88. */
  221.         ITRF_2014_TO_ITRF_1988(ITRFVersion.ITRF_2014, ITRFVersion.ITRF_1988, 2010,
  222.                                25.4, -0.5, -154.8, 0.10, 0.00, 0.26,
  223.                                0.1, -0.5,   -3.3, 0.00, 0.00, 0.02),

  224.         // see http://itrf.ensg.ign.fr/doc_ITRF/Transfo-ITRF2008_ITRFs.txt
  225.         // SOLUTION         Tx       Ty       Tz        D        Rx        Ry        Rz      EPOCH
  226.         // UNITS----------> mm       mm       mm       ppb       .001"     .001"     .001"
  227.         //                         .        .        .         .        .         .         .
  228.         //        RATES     Tx       Ty       Tz        D        Rx        Ry        Rz
  229.         // UNITS----------> mm/y     mm/y     mm/y     ppb/y    .001"/y   .001"/y   .001"/y
  230.         // -----------------------------------------------------------------------------------------
  231.         //   ITRF2005       -2.0     -0.9     -4.7      0.94      0.00      0.00      0.00    2000.0
  232.         //        rates      0.3      0.0      0.0      0.00      0.00      0.00      0.00
  233.         //   ITRF2000       -1.9     -1.7    -10.5      1.34      0.00      0.00      0.00    2000.0
  234.         //        rates      0.1      0.1     -1.8      0.08      0.00      0.00      0.00
  235.         //   ITRF97          4.8      2.6    -33.2      2.92      0.00      0.00      0.06    2000.0
  236.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  237.         //   ITRF96          4.8      2.6    -33.2      2.92      0.00      0.00      0.06    2000.0
  238.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  239.         //   ITRF94          4.8      2.6    -33.2      2.92      0.00      0.00      0.06    2000.0
  240.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  241.         //   ITRF93        -24.0      2.4    -38.6      3.41     -1.71     -1.48     -0.30    2000.0
  242.         //        rates     -2.8     -0.1     -2.4      0.09     -0.11     -0.19      0.07
  243.         //   ITRF92         12.8      4.6    -41.2      2.21      0.00      0.00      0.06    2000.0
  244.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  245.         //   ITRF91         24.8     18.6    -47.2      3.61      0.00      0.00      0.06    2000.0
  246.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  247.         //   ITRF90         22.8     14.6    -63.2      3.91      0.00      0.00      0.06    2000.0
  248.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  249.         //   ITRF89         27.8     38.6   -101.2      7.31      0.00      0.00      0.06    2000.0
  250.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  251.         //   ITRF88         22.8      2.6   -125.2     10.41      0.10      0.00      0.06    2000.0
  252.         //        rates      0.1     -0.5     -3.2      0.09      0.00      0.00      0.02
  253.         // _________________________________________________________________________________________

  254.         /** Transformation from ITRF 2008 To ITRF 2005. */
  255.         ITRF_2008_TO_ITRF_2005(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_2005, 2000,
  256.                                -2.0, -0.9,   -4.7,  0.00,  0.00,  0.00,
  257.                                 0.3,  0.0,    0.0,  0.00,  0.00,  0.00),

  258.         /** Transformation from ITRF 2008 To ITRF 2000. */
  259.         ITRF_2008_TO_ITRF_2000(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_2000, 2000,
  260.                                -1.9, -1.7,  -10.5,  0.00,  0.00,  0.00,
  261.                                 0.1,  0.1,   -1.8,  0.00,  0.00,  0.00),

  262.         /** Transformation from ITRF 2008 To ITRF 97. */
  263.         ITRF_2008_TO_ITRF_1997(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1997, 2000,
  264.                                4.8,  2.6,  -33.2,  0.00,  0.00,  0.06,
  265.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  266.         /** Transformation from ITRF 2008 To ITRF 96. */
  267.         ITRF_2008_TO_ITRF_1996(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1996, 2000,
  268.                                4.8,  2.6,  -33.2,  0.00,  0.00,  0.06,
  269.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  270.         /** Transformation from ITRF 2008 To ITRF 94. */
  271.         ITRF_2008_TO_ITRF_1994(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1994, 2000,
  272.                                4.8,  2.6,  -33.2,  0.00,  0.00,  0.06,
  273.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  274.         /** Transformation from ITRF 2008 To ITRF 93. */
  275.         ITRF_2008_TO_ITRF_1993(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1993, 2000,
  276.                                -24.0,  2.4,  -38.6, -1.71, -1.48, -0.30,
  277.                                -2.8, -0.1,   -2.4, -0.11, -0.19,  0.07),

  278.         /** Transformation from ITRF 2008 To ITRF 92. */
  279.         ITRF_2008_TO_ITRF_1992(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1992, 2000,
  280.                                12.8,  4.6,  -41.2,  0.00,  0.00,  0.06,
  281.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  282.         /** Transformation from ITRF 2008 To ITRF 91. */
  283.         ITRF_2008_TO_ITRF_1991(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1991, 2000,
  284.                                24.8, 18.6,  -47.2,  0.00,  0.00,  0.06,
  285.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  286.         /** Transformation from ITRF 2008 To ITRF 90. */
  287.         ITRF_2008_TO_ITRF_1990(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1990, 2000,
  288.                                22.8, 14.6,  -63.2,  0.00,  0.00,  0.06,
  289.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  290.         /** Transformation from ITRF 2008 To ITRF 89. */
  291.         ITRF_2008_TO_ITRF_1989(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1989, 2000,
  292.                                27.8, 38.6, -101.2,  0.00,  0.00,  0.06,
  293.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02),

  294.         /** Transformation from ITRF 2008 To ITRF 88. */
  295.         ITRF_2008_TO_ITRF_1988(ITRFVersion.ITRF_2008, ITRFVersion.ITRF_1988, 2000,
  296.                                22.8,  2.6, -125.2,  0.10,  0.00,  0.06,
  297.                                0.1, -0.5,   -3.2,  0.00,  0.00,  0.02);

  298.         /** Origin ITRF. */
  299.         private final ITRFVersion origin;

  300.         /** Destination ITRF. */
  301.         private final ITRFVersion destination;

  302.         /** Transformation. */
  303.         private final transient HelmertTransformationWithoutTimeScale transformation;

  304.         /** Simple constructor.
  305.          * @param origin origin ITRF
  306.          * @param destination destination ITRF
  307.          * @param refYear reference year for the epoch of the transform
  308.          * @param t1 translation parameter along X axis (BEWARE, this is in mm)
  309.          * @param t2 translation parameter along Y axis (BEWARE, this is in mm)
  310.          * @param t3 translation parameter along Z axis (BEWARE, this is in mm)
  311.          * @param r1 rotation parameter around X axis (BEWARE, this is in mas)
  312.          * @param r2 rotation parameter around Y axis (BEWARE, this is in mas)
  313.          * @param r3 rotation parameter around Z axis (BEWARE, this is in mas)
  314.          * @param t1Dot rate of translation parameter along X axis (BEWARE, this is in mm/y)
  315.          * @param t2Dot rate of translation parameter along Y axis (BEWARE, this is in mm/y)
  316.          * @param t3Dot rate of translation parameter along Z axis (BEWARE, this is in mm/y)
  317.          * @param r1Dot rate of rotation parameter around X axis (BEWARE, this is in mas/y)
  318.          * @param r2Dot rate of rotation parameter around Y axis (BEWARE, this is in mas/y)
  319.          * @param r3Dot rate of rotation parameter around Z axis (BEWARE, this is in mas/y)
  320.          */
  321.         Predefined(final ITRFVersion origin, final ITRFVersion destination, final int refYear,
  322.                    final double t1, final double t2, final double t3,
  323.                    final double r1, final double r2, final double r3,
  324.                    final double t1Dot, final double t2Dot, final double t3Dot,
  325.                    final double r1Dot, final double r2Dot, final double r3Dot) {
  326.             this.origin         = origin;
  327.             this.destination    = destination;
  328.             this.transformation =
  329.                     new HelmertTransformationWithoutTimeScale(new DateTimeComponents(refYear, 1, 1, 12, 0, 0),
  330.                                               t1, t2, t3, r1, r2, r3, t1Dot, t2Dot, t3Dot, r1Dot, r2Dot, r3Dot);
  331.         }

  332.         /** Get the origin ITRF.
  333.          * @return origin ITRF
  334.          * @since 9.2
  335.          */
  336.         public ITRFVersion getOrigin() {
  337.             return origin;
  338.         }

  339.         /** Get the destination ITRF.
  340.          * @return destination ITRF
  341.          * @since 9.2
  342.          */
  343.         public ITRFVersion getDestination() {
  344.             return destination;
  345.         }

  346.         /** Get the underlying {@link HelmertTransformation}.
  347.          *
  348.          * <p>This method uses the {@link DataContext#getDefault() default data context}.
  349.          *
  350.          * @return underlying {@link HelmertTransformation}
  351.          * @since 9.2
  352.          * @see #getTransformation(TimeScale)
  353.          */
  354.         @DefaultDataContext
  355.         public HelmertTransformation getTransformation() {
  356.             return getTransformation(DataContext.getDefault().getTimeScales().getTT());
  357.         }

  358.         /** Get the underlying {@link HelmertTransformation}.
  359.          * @return underlying {@link HelmertTransformation}
  360.          * @param tt TT time scale.
  361.          * @since 10.1
  362.          */
  363.         public HelmertTransformation getTransformation(final TimeScale tt) {
  364.             return transformation.withTimeScale(tt);
  365.         }

  366.         /** Create an ITRF frame by transforming another ITRF frame.
  367.          *
  368.          * <p>This method uses the {@link DataContext#getDefault() default data context}.
  369.          *
  370.          * @param parent parent ITRF frame
  371.          * @param name name of the frame to create
  372.          * @return new ITRF frame
  373.          * @see #createTransformedITRF(Frame, String, TimeScale)
  374.          */
  375.         @DefaultDataContext
  376.         public Frame createTransformedITRF(final Frame parent, final String name) {
  377.             return createTransformedITRF(parent, name,
  378.                     DataContext.getDefault().getTimeScales().getTT());
  379.         }

  380.         /** Create an ITRF frame by transforming another ITRF frame.
  381.          * @param parent parent ITRF frame
  382.          * @param name name of the frame to create
  383.          * @param tt TT time scale.
  384.          * @return new ITRF frame
  385.          * @since 10.1
  386.          */
  387.         public Frame createTransformedITRF(final Frame parent,
  388.                                            final String name,
  389.                                            final TimeScale tt) {
  390.             return new Frame(parent, getTransformation(tt), name);
  391.         }

  392.         /** Select a predefined transform between two years.
  393.          * @param origin origin year
  394.          * @param destination destination year
  395.          * @return predefined transform from origin to destination, or null if no such predefined transform exist
  396.          * @since 11.2
  397.          */
  398.         public static Predefined selectPredefined(final int origin, final int destination) {
  399.             final Optional<HelmertTransformation.Predefined> optional =
  400.                             Stream.
  401.                             of(HelmertTransformation.Predefined.values()).
  402.                             filter(p -> p.getOrigin().getYear() == origin && p.getDestination().getYear() == destination).
  403.                             findFirst();
  404.             return optional.isPresent() ? optional.get() : null;
  405.         }

  406.     }

  407.     /**
  408.      * A {@link HelmertTransformation} without reference to a {@link TimeScale}. This
  409.      * class is needed to maintain compatibility with Orekit 10.0 since {@link Predefined}
  410.      * is an enum and it had a reference to the TT time scale.
  411.      */
  412.     private static class HelmertTransformationWithoutTimeScale {

  413.         /** Cartesian part of the transform. */
  414.         private final PVCoordinates cartesian;

  415.         /** Global rotation vector (applying rotation is done by computing cross product). */
  416.         private final Vector3D rotationVector;

  417.         /** First time derivative of the rotation (norm representing angular rate). */
  418.         private final Vector3D rotationRate;

  419.         /** Reference epoch of the transform. */
  420.         private final DateTimeComponents epoch;

  421.         /** Build a transform from its primitive operations.
  422.          * @param epoch reference epoch of the transform
  423.          * @param t1 translation parameter along X axis (BEWARE, this is in mm)
  424.          * @param t2 translation parameter along Y axis (BEWARE, this is in mm)
  425.          * @param t3 translation parameter along Z axis (BEWARE, this is in mm)
  426.          * @param r1 rotation parameter around X axis (BEWARE, this is in mas)
  427.          * @param r2 rotation parameter around Y axis (BEWARE, this is in mas)
  428.          * @param r3 rotation parameter around Z axis (BEWARE, this is in mas)
  429.          * @param t1Dot rate of translation parameter along X axis (BEWARE, this is in mm/y)
  430.          * @param t2Dot rate of translation parameter along Y axis (BEWARE, this is in mm/y)
  431.          * @param t3Dot rate of translation parameter along Z axis (BEWARE, this is in mm/y)
  432.          * @param r1Dot rate of rotation parameter around X axis (BEWARE, this is in mas/y)
  433.          * @param r2Dot rate of rotation parameter around Y axis (BEWARE, this is in mas/y)
  434.          * @param r3Dot rate of rotation parameter around Z axis (BEWARE, this is in mas/y)
  435.          */
  436.         HelmertTransformationWithoutTimeScale(
  437.                 final DateTimeComponents epoch,
  438.                 final double t1, final double t2, final double t3,
  439.                 final double r1, final double r2, final double r3,
  440.                 final double t1Dot, final double t2Dot, final double t3Dot,
  441.                 final double r1Dot, final double r2Dot, final double r3Dot) {

  442.             // conversion parameters to SI units
  443.             final double mmToM    = 1.0e-3;
  444.             final double masToRad = 1.0e-3 * Constants.ARC_SECONDS_TO_RADIANS;

  445.             this.epoch          = epoch;
  446.             this.cartesian = new PVCoordinates(new Vector3D(t1 * mmToM,
  447.                     t2 * mmToM,
  448.                     t3 * mmToM),
  449.                     new Vector3D(t1Dot * mmToM / Constants.JULIAN_YEAR,
  450.                             t2Dot * mmToM / Constants.JULIAN_YEAR,
  451.                             t3Dot * mmToM / Constants.JULIAN_YEAR));
  452.             this.rotationVector = new Vector3D(r1 * masToRad,
  453.                     r2 * masToRad,
  454.                     r3 * masToRad);
  455.             this.rotationRate   = new Vector3D(r1Dot * masToRad / Constants.JULIAN_YEAR,
  456.                     r2Dot * masToRad / Constants.JULIAN_YEAR,
  457.                     r3Dot * masToRad / Constants.JULIAN_YEAR);

  458.         }

  459.         /**
  460.          * Get the Helmert transformation with reference to the given time scale.
  461.          *
  462.          * @param tt TT time scale.
  463.          * @return Helmert transformation.
  464.          */
  465.         public HelmertTransformation withTimeScale(final TimeScale tt) {
  466.             return new HelmertTransformation(cartesian, rotationVector, rotationRate,
  467.                     new AbsoluteDate(epoch, tt));
  468.         }

  469.     }

  470.     /** Cartesian part of the transform. */
  471.     private final PVCoordinates cartesian;

  472.     /** Global rotation vector (applying rotation is done by computing cross product). */
  473.     private final Vector3D rotationVector;

  474.     /** First time derivative of the rotation (norm representing angular rate). */
  475.     private final Vector3D rotationRate;

  476.     /** Reference epoch of the transform. */
  477.     private final AbsoluteDate epoch;

  478.     /** Build a transform from its primitive operations.
  479.      * @param epoch reference epoch of the transform
  480.      * @param t1 translation parameter along X axis (BEWARE, this is in mm)
  481.      * @param t2 translation parameter along Y axis (BEWARE, this is in mm)
  482.      * @param t3 translation parameter along Z axis (BEWARE, this is in mm)
  483.      * @param r1 rotation parameter around X axis (BEWARE, this is in mas)
  484.      * @param r2 rotation parameter around Y axis (BEWARE, this is in mas)
  485.      * @param r3 rotation parameter around Z axis (BEWARE, this is in mas)
  486.      * @param t1Dot rate of translation parameter along X axis (BEWARE, this is in mm/y)
  487.      * @param t2Dot rate of translation parameter along Y axis (BEWARE, this is in mm/y)
  488.      * @param t3Dot rate of translation parameter along Z axis (BEWARE, this is in mm/y)
  489.      * @param r1Dot rate of rotation parameter around X axis (BEWARE, this is in mas/y)
  490.      * @param r2Dot rate of rotation parameter around Y axis (BEWARE, this is in mas/y)
  491.      * @param r3Dot rate of rotation parameter around Z axis (BEWARE, this is in mas/y)
  492.      */
  493.     public HelmertTransformation(final AbsoluteDate epoch,
  494.                                  final double t1, final double t2, final double t3,
  495.                                  final double r1, final double r2, final double r3,
  496.                                  final double t1Dot, final double t2Dot, final double t3Dot,
  497.                                  final double r1Dot, final double r2Dot, final double r3Dot) {

  498.         // conversion parameters to SI units
  499.         final double mmToM    = 1.0e-3;
  500.         final double masToRad = 1.0e-3 * Constants.ARC_SECONDS_TO_RADIANS;

  501.         this.epoch          = epoch;
  502.         this.cartesian = new PVCoordinates(new Vector3D(t1 * mmToM,
  503.                                                         t2 * mmToM,
  504.                                                         t3 * mmToM),
  505.                                            new Vector3D(t1Dot * mmToM / Constants.JULIAN_YEAR,
  506.                                                         t2Dot * mmToM / Constants.JULIAN_YEAR,
  507.                                                         t3Dot * mmToM / Constants.JULIAN_YEAR));
  508.         this.rotationVector = new Vector3D(r1 * masToRad,
  509.                                            r2 * masToRad,
  510.                                            r3 * masToRad);
  511.         this.rotationRate   = new Vector3D(r1Dot * masToRad / Constants.JULIAN_YEAR,
  512.                                            r2Dot * masToRad / Constants.JULIAN_YEAR,
  513.                                            r3Dot * masToRad / Constants.JULIAN_YEAR);

  514.     }

  515.     /**
  516.      * Private constructor.
  517.      *
  518.      * @param cartesian      part of the transform.
  519.      * @param rotationVector global rotation vector.
  520.      * @param rotationRate   time derivative of rotation.
  521.      * @param epoch          of transform.
  522.      */
  523.     private HelmertTransformation(final PVCoordinates cartesian,
  524.                                   final Vector3D rotationVector,
  525.                                   final Vector3D rotationRate,
  526.                                   final AbsoluteDate epoch) {
  527.         this.cartesian = cartesian;
  528.         this.rotationVector = rotationVector;
  529.         this.rotationRate = rotationRate;
  530.         this.epoch = epoch;
  531.     }

  532.     /** Get the reference epoch of the transform.
  533.      * @return reference epoch of the transform
  534.      */
  535.     public AbsoluteDate getEpoch() {
  536.         return epoch;
  537.     }

  538.     /** {@inheritDoc} */
  539.     @Override
  540.     public Transform getTransform(final AbsoluteDate date) {

  541.         // compute parameters evolution since reference epoch
  542.         final double dt = date.durationFrom(epoch);
  543.         final Vector3D dR = new Vector3D(1, rotationVector, dt, rotationRate);

  544.         // build translation part
  545.         final Transform translationTransform = new Transform(date, cartesian.shiftedBy(dt));

  546.         // build rotation part
  547.         final double angle = dR.getNorm();
  548.         final Transform rotationTransform =
  549.                 new Transform(date,
  550.                               (angle < Precision.SAFE_MIN) ?
  551.                               Rotation.IDENTITY :
  552.                               new Rotation(dR, angle, RotationConvention.VECTOR_OPERATOR),
  553.                               rotationRate);

  554.         // combine both parts
  555.         return new Transform(date, translationTransform, rotationTransform);

  556.     }

  557.     /** {@inheritDoc} */
  558.     @Override
  559.     public StaticTransform getStaticTransform(final AbsoluteDate date) {

  560.         // compute parameters evolution since reference epoch
  561.         final double dt = date.durationFrom(epoch);
  562.         final Vector3D dR = new Vector3D(1, rotationVector, dt, rotationRate);

  563.         // build translation part
  564.         final Vector3D translation = cartesian.shiftedBy(dt).getPosition();

  565.         // build rotation part
  566.         final double angle = dR.getNorm();
  567.         final Rotation rotation = (angle < Precision.SAFE_MIN) ?
  568.                 Rotation.IDENTITY :
  569.                 new Rotation(dR, angle, RotationConvention.VECTOR_OPERATOR);

  570.         // combine both parts
  571.         return StaticTransform.of(date, translation, rotation);

  572.     }

  573.     /** {@inheritDoc} */
  574.     @Override
  575.     public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {

  576.         // compute parameters evolution since reference epoch
  577.         final T dt = date.durationFrom(epoch);
  578.         final FieldVector3D<T> dR = new FieldVector3D<>(date.getField().getOne(), rotationVector,
  579.                                                         dt, rotationRate);

  580.         // build translation part
  581.         final FieldTransform<T> translationTransform =
  582.                         new FieldTransform<>(date,
  583.                                              new FieldPVCoordinates<>(date.getField(), cartesian).shiftedBy(dt));

  584.         // build rotation part
  585.         final T angle = dR.getNorm();
  586.         final FieldTransform<T> rotationTransform =
  587.                 new FieldTransform<>(date,
  588.                                     (angle.getReal() < Precision.SAFE_MIN) ?
  589.                                      FieldRotation.getIdentity(date.getField()) :
  590.                                     new FieldRotation<>(dR, angle, RotationConvention.VECTOR_OPERATOR),
  591.                                     new FieldVector3D<>(date.getField(), rotationRate));

  592.         // combine both parts
  593.         return new FieldTransform<>(date, translationTransform, rotationTransform);

  594.     }

  595.     /** {@inheritDoc} */
  596.     @Override
  597.     public <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {

  598.         // field
  599.         final Field<T> field = date.getField();

  600.         // compute parameters evolution since reference epoch
  601.         final T dt = date.durationFrom(epoch);
  602.         final FieldVector3D<T> dR = new FieldVector3D<>(field.getOne(), rotationVector, dt, rotationRate);

  603.         // build translation part
  604.         final FieldVector3D<T> translation = new FieldPVCoordinates<>(date.getField(), cartesian).shiftedBy(dt).getPosition();

  605.         // build rotation part
  606.         final T angle = dR.getNorm();
  607.         final FieldRotation<T> rotation = (angle.getReal() < Precision.SAFE_MIN) ?
  608.                 FieldRotation.getIdentity(field) :
  609.                 new FieldRotation<>(dR, angle, RotationConvention.VECTOR_OPERATOR);

  610.         // combine both parts
  611.         return FieldStaticTransform.of(date, translation, rotation);

  612.     }

  613. }