1   /* Copyright 2002-2018 CS Systèmes d'Information
2    * Licensed to CS Systèmes d'Information (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.propagation.analytical.tle;
18  
19  import org.hipparchus.util.FastMath;
20  import org.hipparchus.util.MathUtils;
21  import org.orekit.attitudes.AttitudeProvider;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.time.AbsoluteDate;
24  import org.orekit.time.TimeScalesFactory;
25  import org.orekit.utils.Constants;
26  
27  /** This class contains methods to compute propagated coordinates with the SDP4 model.
28   * <p>
29   * The user should not bother in this class since it is handled internally by the
30   * {@link TLEPropagator}.
31   * </p>
32   * <p>This implementation is largely inspired from the paper and source code <a
33   * href="http://www.celestrak.com/publications/AIAA/2006-6753/">Revisiting Spacetrack
34   * Report #3</a> and is fully compliant with its results and tests cases.</p>
35   * @author Felix R. Hoots, Ronald L. Roehrich, December 1980 (original fortran)
36   * @author David A. Vallado, Paul Crawford, Richard Hujsak, T.S. Kelso (C++ translation and improvements)
37   * @author Fabien Maussion (java translation)
38   */
39  abstract class SDP4  extends TLEPropagator {
40  
41      // CHECKSTYLE: stop VisibilityModifier check
42  
43      /** New perigee argument. */
44      protected double omgadf;
45  
46      /** New mean motion. */
47      protected double xn;
48  
49      /** Parameter for xl computation. */
50      protected double xll;
51  
52      /** New eccentricity. */
53      protected double em;
54  
55      /** New inclination. */
56      protected double xinc;
57  
58      // CHECKSTYLE: resume VisibilityModifier check
59  
60      /** Constructor for a unique initial TLE.
61       * @param initialTLE the TLE to propagate.
62       * @param attitudeProvider provider for attitude computation
63       * @param mass spacecraft mass (kg)
64       * @exception OrekitException if some specific error occurs
65       */
66      protected SDP4(final TLE initialTLE, final AttitudeProvider attitudeProvider,
67                     final double mass) throws OrekitException {
68          super(initialTLE, attitudeProvider, mass);
69      }
70  
71      /** Initialization proper to each propagator (SGP or SDP).
72       * @exception OrekitException when UTC time steps can't be read
73       */
74      protected void sxpInitialize() throws OrekitException {
75          luniSolarTermsComputation();
76      }  // End of initialization
77  
78      /** Propagation proper to each propagator (SGP or SDP).
79       * @param tSince the offset from initial epoch (minutes)
80       */
81      protected void sxpPropagate(final double tSince) {
82  
83          // Update for secular gravity and atmospheric drag
84          omgadf = tle.getPerigeeArgument() + omgdot * tSince;
85          final double xnoddf = tle.getRaan() + xnodot * tSince;
86          final double tSinceSq = tSince * tSince;
87          xnode = xnoddf + xnodcf * tSinceSq;
88          xn = xn0dp;
89  
90          // Update for deep-space secular effects
91          xll = tle.getMeanAnomaly() + xmdot * tSince;
92  
93          deepSecularEffects(tSince);
94  
95          final double tempa = 1 - c1 * tSince;
96          a   = FastMath.pow(TLEConstants.XKE / xn, TLEConstants.TWO_THIRD) * tempa * tempa;
97          em -= tle.getBStar() * c4 * tSince;
98  
99          // Update for deep-space periodic effects
100         xll += xn0dp * t2cof * tSinceSq;
101 
102         deepPeriodicEffects(tSince);
103 
104         xl = xll + omgadf + xnode;
105 
106         // Dundee change:  Reset cosio,  sinio for new xinc:
107         cosi0 = FastMath.cos(xinc);
108         sini0 = FastMath.sin(xinc);
109         e = em;
110         i = xinc;
111         omega = omgadf;
112         // end of calculus, go for PV computation
113     }
114 
115     /** Computes SPACETRACK#3 compliant earth rotation angle.
116      * @param date the current date
117      * @return the ERA (rad)
118      * @exception OrekitException when UTC time steps can't be read
119      */
120     protected static double thetaG(final AbsoluteDate date) throws OrekitException {
121 
122         // Reference:  The 1992 Astronomical Almanac, page B6.
123         final double omega_E = 1.00273790934;
124         final double jd = (date.durationFrom(AbsoluteDate.JULIAN_EPOCH) +
125                            date.timeScalesOffset(TimeScalesFactory.getUTC(), TimeScalesFactory.getTT())
126                           ) / Constants.JULIAN_DAY;
127 
128         // Earth rotations per sidereal day (non-constant)
129         final double UT = (jd + 0.5) % 1;
130         final double seconds_per_day = Constants.JULIAN_DAY;
131         final double jd_2000 = 2451545.0;   /* 1.5 Jan 2000 = JD 2451545. */
132         final double t_cen = (jd - UT - jd_2000) / 36525.;
133         double GMST = 24110.54841 +
134                       t_cen * (8640184.812866 + t_cen * (0.093104 - t_cen * 6.2E-6));
135         GMST = (GMST + seconds_per_day * omega_E * UT) % seconds_per_day;
136         if (GMST < 0.) {
137             GMST += seconds_per_day;
138         }
139 
140         return MathUtils.TWO_PI * GMST / seconds_per_day;
141 
142     }
143 
144     /** Computes luni - solar terms from initial coordinates and epoch.
145      * @exception OrekitException when UTC time steps can't be read
146      */
147     protected abstract void luniSolarTermsComputation() throws OrekitException;
148 
149     /** Computes secular terms from current coordinates and epoch.
150      * @param t offset from initial epoch (min)
151      */
152     protected abstract void deepSecularEffects(double t);
153 
154     /** Computes periodic terms from current coordinates and epoch.
155      * @param t offset from initial epoch (min)
156      */
157     protected abstract void deepPeriodicEffects(double t);
158 
159 }