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.propagation.semianalytical.dsst.utilities;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21  import org.hipparchus.util.FastMath;
22  import org.hipparchus.util.MathUtils;
23  import org.orekit.frames.Frame;
24  import org.orekit.orbits.FieldOrbit;
25  import org.orekit.time.FieldAbsoluteDate;
26  
27  /** Container class for common parameters used by all DSST forces.
28   *  <p>
29   *  Most of them are defined in Danielson paper at § 2.1.
30   *  </p>
31   *  @author Bryan Cazabonne
32   * @param <T> type of the field elements
33   */
34  public class FieldAuxiliaryElements<T extends CalculusFieldElement<T>> {
35  
36      /** Orbit. */
37      private final FieldOrbit<T> orbit;
38  
39      /** Orbit date. */
40      private final FieldAbsoluteDate<T> date;
41  
42      /** Orbit frame. */
43      private final Frame frame;
44  
45      /** Eccentricity. */
46      private final T ecc;
47  
48      /** Keplerian mean motion. */
49      private final T n;
50  
51      /** Keplerian period. */
52      private final T period;
53  
54      /** Semi-major axis. */
55      private final T sma;
56  
57      /** x component of eccentricity vector. */
58      private final T k;
59  
60      /** y component of eccentricity vector. */
61      private final T h;
62  
63      /** x component of inclination vector. */
64      private final T q;
65  
66      /** y component of inclination vector. */
67      private final T p;
68  
69      /** Mean longitude. */
70      private final T lm;
71  
72      /** True longitude. */
73      private final T lv;
74  
75      /** Eccentric longitude. */
76      private final T le;
77  
78      /** Retrograde factor I.
79       *  <p>
80       *  DSST model needs equinoctial orbit as internal representation.
81       *  Classical equinoctial elements have discontinuities when inclination
82       *  is close to zero. In this representation, I = +1. <br>
83       *  To avoid this discontinuity, another representation exists and equinoctial
84       *  elements can be expressed in a different way, called "retrograde" orbit.
85       *  This implies I = -1. <br>
86       *  As Orekit doesn't implement the retrograde orbit, I is always set to +1.
87       *  But for the sake of consistency with the theory, the retrograde factor
88       *  has been kept in the formulas.
89       *  </p>
90       */
91      private final int    I;
92  
93      /** B = sqrt(1 - h² - k²). */
94      private final T B;
95  
96      /** C = 1 + p² + q². */
97      private final T C;
98  
99      /** Equinoctial frame f vector. */
100     private final FieldVector3D<T> f;
101 
102     /** Equinoctial frame g vector. */
103     private final FieldVector3D<T> g;
104 
105     /** Equinoctial frame w vector. */
106     private final FieldVector3D<T> w;
107 
108     /** Direction cosine α. */
109     private final T alpha;
110 
111     /** Direction cosine β. */
112     private final T beta;
113 
114     /** Direction cosine γ. */
115     private final T gamma;
116 
117     /** Simple constructor.
118      * @param orbit related mean orbit for auxiliary elements
119      * @param retrogradeFactor retrograde factor I [Eq. 2.1.2-(2)]
120      */
121     public FieldAuxiliaryElements(final FieldOrbit<T> orbit, final int retrogradeFactor) {
122 
123         final T pi = orbit.getDate().getField().getZero().getPi();
124 
125         // Orbit
126         this.orbit = orbit;
127 
128         // Date of the orbit
129         date = orbit.getDate();
130 
131         // Orbit definition frame
132         frame = orbit.getFrame();
133 
134         // Eccentricity
135         ecc = orbit.getE();
136 
137         // Keplerian mean motion
138         n = orbit.getKeplerianMeanMotion();
139 
140         // Keplerian period
141         period = orbit.getKeplerianPeriod();
142 
143         // Equinoctial elements [Eq. 2.1.2-(1)]
144         sma = orbit.getA();
145         k   = orbit.getEquinoctialEx();
146         h   = orbit.getEquinoctialEy();
147         q   = orbit.getHx();
148         p   = orbit.getHy();
149         lm  = MathUtils.normalizeAngle(orbit.getLM(), pi);
150         lv  = MathUtils.normalizeAngle(orbit.getLv(), pi);
151         le  = MathUtils.normalizeAngle(orbit.getLE(), pi);
152 
153         // Retrograde factor [Eq. 2.1.2-(2)]
154         I = retrogradeFactor;
155 
156         final T k2 = k.multiply(k);
157         final T h2 = h.multiply(h);
158         final T q2 = q.multiply(q);
159         final T p2 = p.multiply(p);
160 
161         // A, B, C parameters [Eq. 2.1.6-(1)]
162         B = FastMath.sqrt(k2.add(h2).negate().add(1.));
163         C = q2.add(p2).add(1);
164 
165         // Equinoctial reference frame [Eq. 2.1.4-(1)]
166         final T ooC = C.reciprocal();
167         final T px2 = p.multiply(2.);
168         final T qx2 = q.multiply(2.);
169         final T pq2 = px2.multiply(q);
170         f = new FieldVector3D<>(ooC, new FieldVector3D<>(p2.negate().add(1.).add(q2), pq2, px2.multiply(I).negate()));
171         g = new FieldVector3D<>(ooC, new FieldVector3D<>(pq2.multiply(I), (p2.add(1.).subtract(q2)).multiply(I), qx2));
172         w = new FieldVector3D<>(ooC, new FieldVector3D<>(px2, qx2.negate(), (p2.add(q2).negate().add(1.)).multiply(I)));
173 
174         // Direction cosines for central body [Eq. 2.1.9-(1)]
175         alpha = (T) f.getZ();
176         beta  = (T) g.getZ();
177         gamma = (T) w.getZ();
178     }
179 
180     /** Get the orbit.
181      * @return the orbit
182      */
183     public FieldOrbit<T> getOrbit() {
184         return orbit;
185     }
186 
187     /** Get the date of the orbit.
188      * @return the date
189      */
190     public FieldAbsoluteDate<T> getDate() {
191         return date;
192     }
193 
194     /** Get the definition frame of the orbit.
195      * @return the definition frame
196      */
197     public Frame getFrame() {
198         return frame;
199     }
200 
201     /** Get the eccentricity.
202      * @return ecc
203      */
204     public T getEcc() {
205         return ecc;
206     }
207 
208     /** Get the Keplerian mean motion.
209      * @return n
210      */
211     public T getMeanMotion() {
212         return n;
213     }
214 
215     /** Get the Keplerian period.
216      * @return period
217      */
218     public T getKeplerianPeriod() {
219         return period;
220     }
221 
222     /** Get the semi-major axis.
223      * @return the semi-major axis a
224      */
225     public T getSma() {
226         return sma;
227     }
228 
229     /** Get the x component of eccentricity vector.
230      * <p>
231      * This element called k in DSST corresponds to ex
232      * for the {@link org.orekit.orbits.EquinoctialOrbit}
233      * </p>
234      * @return k
235      */
236     public T getK() {
237         return k;
238     }
239 
240     /** Get the y component of eccentricity vector.
241      * <p>
242      * This element called h in DSST corresponds to ey
243      * for the {@link org.orekit.orbits.EquinoctialOrbit}
244      * </p>
245      * @return h
246      */
247     public T getH() {
248         return h;
249     }
250 
251     /** Get the x component of inclination vector.
252      * <p>
253      * This element called q in DSST corresponds to hx
254      * for the {@link org.orekit.orbits.EquinoctialOrbit}
255      * </p>
256      * @return q
257      */
258     public T getQ() {
259         return q;
260     }
261 
262     /** Get the y component of inclination vector.
263      * <p>
264      * This element called p in DSST corresponds to hy
265      * for the {@link org.orekit.orbits.EquinoctialOrbit}
266      * </p>
267      * @return p
268      */
269     public T getP() {
270         return p;
271     }
272 
273     /** Get the mean longitude.
274      * @return lm
275      */
276     public T getLM() {
277         return lm;
278     }
279 
280     /** Get the true longitude.
281      * @return lv
282      */
283     public T getLv() {
284         return lv;
285     }
286 
287     /** Get the eccentric longitude.
288      * @return le
289      */
290     public T getLe() {
291         return le;
292     }
293 
294     /** Get the retrograde factor.
295      * @return the retrograde factor I
296      */
297     public int getRetrogradeFactor() {
298         return I;
299     }
300 
301     /** Get B = sqrt(1 - e²).
302      * @return B
303      */
304     public T getB() {
305         return B;
306     }
307 
308     /** Get C = 1 + p² + q².
309      * @return C
310      */
311     public T getC() {
312         return C;
313     }
314 
315     /** Get equinoctial frame vector f.
316      * @return f vector
317      */
318     public FieldVector3D<T> getVectorF() {
319         return f;
320     }
321 
322     /** Get equinoctial frame vector g.
323      * @return g vector
324      */
325     public FieldVector3D<T> getVectorG() {
326         return g;
327     }
328 
329     /** Get equinoctial frame vector w.
330      * @return w vector
331      */
332     public FieldVector3D<T> getVectorW() {
333         return w;
334     }
335 
336     /** Get direction cosine α for central body.
337      * @return α
338      */
339     public T getAlpha() {
340         return alpha;
341     }
342 
343     /** Get direction cosine β for central body.
344      * @return β
345      */
346     public T getBeta() {
347         return beta;
348     }
349 
350     /** Get direction cosine γ for central body.
351      * @return γ
352      */
353     public T getGamma() {
354         return gamma;
355     }
356 
357     /** Transforms the FieldAuxiliaryElements instance into an AuxiliaryElements instance.
358      * @return the AuxiliaryElements instance
359      * @since 11.3.3
360      */
361     public AuxiliaryElements toAuxiliaryElements() {
362         return new AuxiliaryElements(orbit.toOrbit(), getRetrogradeFactor());
363     }
364 }