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.Vector3D;
25  import org.hipparchus.util.MathUtils;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.time.DateComponents;
28  import org.orekit.time.FieldAbsoluteDate;
29  import org.orekit.time.TimeScales;
30  import org.orekit.utils.Constants;
31  
32  /** Veis 1950 Frame.
33   * <p>Its parent frame is the {@link GTODProvider} without EOP correction application.
34   * <p>This frame is mainly provided for consistency with legacy softwares.</p>
35   * @author Pascal Parraud
36   */
37  class VEISProvider implements TransformProvider {
38  
39      /** Serializable UID. */
40      private static final long serialVersionUID = 20130530L;
41  
42      /** 1st coef for Veis sidereal time computation in radians (100.075542 deg). */
43      private static final double VST0 = 1.746647708617871;
44  
45      /** 2nd coef for Veis sidereal time computation in rad/s (0.985612288 deg/s). */
46      private static final double VST1 = 0.17202179573714597e-1;
47  
48      /** Veis sidereal time derivative in rad/s. */
49      private static final double VSTD = 7.292115146705209e-5;
50  
51      /** Set of time scales to use. */
52      private final transient TimeScales timeScales;
53  
54      /** Reference date. */
55      private final AbsoluteDate vstReference;
56  
57      /**
58       * Constructor for the singleton.
59       *
60       * @param timeScales to use when computing the transform.
61       */
62      VEISProvider(final TimeScales timeScales) {
63          this.timeScales = timeScales;
64          this.vstReference =
65                  new AbsoluteDate(DateComponents.FIFTIES_EPOCH, timeScales.getTAI());
66      }
67  
68      /** {@inheritDoc} */
69      @Override
70      public Transform getTransform(final AbsoluteDate date) {
71  
72          // offset from FIFTIES epoch (UT1 scale)
73          final double dtai = date.durationFrom(vstReference);
74          final double dutc = timeScales.getUTC().offsetFromTAI(date);
75          final double dut1 = 0.0; // fixed at 0 since Veis parent is GTOD frame WITHOUT EOP corrections
76  
77          final double tut1 = dtai + dutc + dut1;
78          final double ttd  = tut1 / Constants.JULIAN_DAY;
79          final double rdtt = ttd - (int) ttd;
80  
81          // compute Veis sidereal time, in radians
82          final double vst = (VST0 + VST1 * ttd + MathUtils.TWO_PI * rdtt) % MathUtils.TWO_PI;
83  
84          // compute angular rotation of Earth, in rad/s
85          final Vector3D rotationRate = new Vector3D(-VSTD, Vector3D.PLUS_K);
86  
87          // set up the transform from parent GTOD
88          return new Transform(date,
89                               new Rotation(Vector3D.PLUS_K, vst, RotationConvention.VECTOR_OPERATOR),
90                               rotationRate);
91  
92      }
93  
94      /** {@inheritDoc} */
95      @Override
96      public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
97  
98          // offset from FIFTIES epoch (UT1 scale)
99          final T dtai = date.durationFrom(vstReference);
100         final double dutc = timeScales.getUTC().offsetFromTAI(date.toAbsoluteDate());
101         final double dut1 = 0.0; // fixed at 0 since Veis parent is GTOD frame WITHOUT EOP corrections
102 
103         final T tut1 = dtai.add(dutc + dut1);
104         final T ttd  = tut1.divide(Constants.JULIAN_DAY);
105         final T rdtt = ttd.subtract((int) ttd.getReal());
106 
107         // compute Veis sidereal time, in radians
108         final T vst = ttd.multiply(VST1).add(rdtt.multiply(MathUtils.TWO_PI)).add(VST0).remainder(MathUtils.TWO_PI);
109 
110         // compute angular rotation of Earth, in rad/s
111         final FieldVector3D<T> rotationRate = new FieldVector3D<>(date.getField().getZero().newInstance(-VSTD),
112                                                                   Vector3D.PLUS_K);
113 
114         // set up the transform from parent GTOD
115         return new FieldTransform<>(date,
116                                     new FieldRotation<>(FieldVector3D.getPlusK(date.getField()), vst,
117                                                         RotationConvention.VECTOR_OPERATOR),
118                                     rotationRate);
119 
120     }
121 
122 }