1   /* Copyright 2002-2025 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      /** S' rate in radians per julian century.
39       * Approximately -47 microarcsecond per julian century (Lambert and Bizouard, 2002)
40       */
41      private static final double S_PRIME_RATE = -47e-6 * Constants.ARC_SECONDS_TO_RADIANS;
42  
43      /** EOP history. */
44      private final EOPHistory eopHistory;
45  
46      /** Simple constructor.
47       * @param eopHistory EOP history
48       */
49      ITRFProvider(final EOPHistory eopHistory) {
50          this.eopHistory = eopHistory;
51      }
52  
53      /** {@inheritDoc} */
54      @Override
55      public EOPHistory getEOPHistory() {
56          return eopHistory;
57      }
58  
59      /** {@inheritDoc} */
60      @Override
61      public ITRFProvider getNonInterpolatingProvider() {
62          return new ITRFProvider(eopHistory.getEOPHistoryWithoutCachedTidalCorrection());
63      }
64  
65      /** {@inheritDoc} */
66      @Override
67      public Transform getTransform(final AbsoluteDate date) {
68  
69          // offset from J2000 epoch in Julian centuries
70          final double tts = date.durationFrom(eopHistory.getTimeScales().getJ2000Epoch());
71          final double ttc =  tts / Constants.JULIAN_CENTURY;
72  
73          // pole correction parameters
74          final PoleCorrection eop = eopHistory.getPoleCorrection(date);
75  
76          // pole motion in terrestrial frame
77          final Rotation wRot = new Rotation(RotationOrder.XYZ, RotationConvention.FRAME_TRANSFORM,
78                                             eop.getYp(), eop.getXp(), -S_PRIME_RATE * ttc);
79  
80          // combined effects
81          final Rotation combined = wRot.revert();
82  
83          // set up the transform from parent TIRF
84          return new Transform(date, combined, Vector3D.ZERO);
85  
86      }
87  
88      /** {@inheritDoc} */
89      @Override
90      public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
91  
92          // offset from J2000 epoch in Julian centuries
93          final T tts = date.durationFrom(eopHistory.getTimeScales().getJ2000Epoch());
94          final T ttc =  tts.divide(Constants.JULIAN_CENTURY);
95  
96          // pole correction parameters
97          final FieldPoleCorrection<T> eop = eopHistory.getPoleCorrection(date);
98  
99          // pole motion in terrestrial frame
100         final FieldRotation<T> wRot = new FieldRotation<>(RotationOrder.XYZ, RotationConvention.FRAME_TRANSFORM,
101                                                           eop.getYp(),
102                                                           eop.getXp(),
103                                                           ttc.multiply(-S_PRIME_RATE));
104 
105         // combined effects
106         final FieldRotation<T> combined = wRot.revert();
107 
108         // set up the transform from parent TIRF
109         return new FieldTransform<>(date, combined, FieldVector3D.getZero(date.getField()));
110 
111     }
112 
113 }