1   /* Copyright 2002-2024 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 org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.geometry.euclidean.threed.FieldRotation;
21  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22  import org.hipparchus.geometry.euclidean.threed.Rotation;
23  import org.hipparchus.geometry.euclidean.threed.RotationConvention;
24  import org.hipparchus.geometry.euclidean.threed.RotationOrder;
25  import org.hipparchus.geometry.euclidean.threed.Vector3D;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.time.FieldAbsoluteDate;
28  import org.orekit.utils.Constants;
29  
30  
31  /** International Terrestrial Reference Frame.
32   * <p> Handles pole motion effects and depends on {@link TIRFProvider}, its
33   * parent frame.</p>
34   * @author Luc Maisonobe
35   */
36  class ITRFProvider implements EOPBasedTransformProvider {
37  
38      /** Serializable UID. */
39      private static final long serialVersionUID = 20130922L;
40  
41      /** S' rate in radians per julian century.
42       * Approximately -47 microarcsecond per julian century (Lambert and Bizouard, 2002)
43       */
44      private static final double S_PRIME_RATE = -47e-6 * Constants.ARC_SECONDS_TO_RADIANS;
45  
46      /** EOP history. */
47      private final EOPHistory eopHistory;
48  
49      /** Simple constructor.
50       * @param eopHistory EOP history
51       */
52      ITRFProvider(final EOPHistory eopHistory) {
53          this.eopHistory = eopHistory;
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      public EOPHistory getEOPHistory() {
59          return eopHistory;
60      }
61  
62      /** {@inheritDoc} */
63      @Override
64      public ITRFProvider getNonInterpolatingProvider() {
65          return new ITRFProvider(eopHistory.getEOPHistoryWithoutCachedTidalCorrection());
66      }
67  
68      /** {@inheritDoc} */
69      @Override
70      public Transform getTransform(final AbsoluteDate date) {
71  
72          // offset from J2000 epoch in Julian centuries
73          final double tts = date.durationFrom(eopHistory.getTimeScales().getJ2000Epoch());
74          final double ttc =  tts / Constants.JULIAN_CENTURY;
75  
76          // pole correction parameters
77          final PoleCorrection eop = eopHistory.getPoleCorrection(date);
78  
79          // pole motion in terrestrial frame
80          final Rotation wRot = new Rotation(RotationOrder.XYZ, RotationConvention.FRAME_TRANSFORM,
81                                             eop.getYp(), eop.getXp(), -S_PRIME_RATE * ttc);
82  
83          // combined effects
84          final Rotation combined = wRot.revert();
85  
86          // set up the transform from parent TIRF
87          return new Transform(date, combined, Vector3D.ZERO);
88  
89      }
90  
91      /** {@inheritDoc} */
92      @Override
93      public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
94  
95          // offset from J2000 epoch in Julian centuries
96          final T tts = date.durationFrom(eopHistory.getTimeScales().getJ2000Epoch());
97          final T ttc =  tts.divide(Constants.JULIAN_CENTURY);
98  
99          // pole correction parameters
100         final FieldPoleCorrection<T> eop = eopHistory.getPoleCorrection(date);
101 
102         // pole motion in terrestrial frame
103         final FieldRotation<T> wRot = new FieldRotation<>(RotationOrder.XYZ, RotationConvention.FRAME_TRANSFORM,
104                                                           eop.getYp(),
105                                                           eop.getXp(),
106                                                           ttc.multiply(-S_PRIME_RATE));
107 
108         // combined effects
109         final FieldRotation<T> combined = wRot.revert();
110 
111         // set up the transform from parent TIRF
112         return new FieldTransform<>(date, combined, FieldVector3D.getZero(date.getField()));
113 
114     }
115 
116 }