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.propagation.analytical.gnss.data;
18  
19  import org.orekit.annotation.DefaultDataContext;
20  import org.orekit.attitudes.AttitudeProvider;
21  import org.orekit.data.DataContext;
22  import org.orekit.frames.Frame;
23  import org.orekit.frames.Frames;
24  import org.orekit.propagation.analytical.gnss.GLONASSAnalyticalPropagator;
25  import org.orekit.propagation.analytical.gnss.GLONASSAnalyticalPropagatorBuilder;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.time.DateComponents;
28  import org.orekit.time.GLONASSDate;
29  import org.orekit.time.TimeComponents;
30  import org.orekit.time.TimeScale;
31  import org.orekit.utils.IERSConventions;
32  
33  /**
34   * This class holds a GLONASS almanac as read from .agl files.
35   *
36   * @author Bryan Cazabonne
37   * @since 10.0
38   *
39   */
40  public class GLONASSAlmanac implements GLONASSOrbitalElements {
41  
42      /** Frequency channel (-7...6). */
43      private final int channel;
44  
45      /** Health status. */
46      private final int health;
47  
48      /** Day of Almanac. */
49      private final int day;
50  
51      /** Month of Almanac. */
52      private final int month;
53  
54      /** Year of Almanac. */
55      private final int year;
56  
57      /** Reference time of the almanac. */
58      private final double ta;
59  
60      /** Greenwich longitude of ascending node of orbit. */
61      private final double lambda;
62  
63      /** Correction to the mean value of inclination. */
64      private final double deltaI;
65  
66      /** Argument of perigee. */
67      private final double pa;
68  
69      /** Eccentricity. */
70      private final double ecc;
71  
72      /** Correction to the mean value of Draconian period. */
73      private final double deltaT;
74  
75      /** Rate of change of orbital period. */
76      private final double deltaTDot;
77  
78      /** Correction from GLONASS to UTC. */
79      private final double tGlo2UTC;
80  
81      /** Correction to GPS time relative GLONASS. */
82      private final double tGPS2Glo;
83  
84      /**  Correction of time relative to GLONASS system time. */
85      private final double tGlo;
86  
87      /** GLONASS time scale. */
88      private final TimeScale glonass;
89  
90      /**
91       * Constructor.
92       *
93       * <p>This method uses the {@link DataContext#getDefault() default data context}.
94       *
95       * @param channel the frequency channel from -7 to 6)
96       * @param health the Health status
97       * @param day the day of Almanac
98       * @param month the month of Almanac
99       * @param year the year of Almanac
100      * @param ta the reference time of the almanac (s)
101      * @param lambda the Greenwich longitude of ascending node of orbit (rad)
102      * @param deltaI the correction to the mean value of inclination (rad)
103      * @param pa the argument of perigee (rad)
104      * @param ecc the eccentricity
105      * @param deltaT the correction to the mean value of Draconian period (s)
106      * @param deltaTDot the rate of change of orbital period
107      * @param tGlo2UTC the correction from GLONASS to UTC (s)
108      * @param tGPS2Glo the correction to GPS time relative GLONASS (s)
109      * @param tGlo the correction of time relative to GLONASS system time (s)
110      * @see #GLONASSAlmanac(int, int, int, int, int, double, double, double, double,
111      * double, double, double, double, double, double, TimeScale)
112      */
113     @DefaultDataContext
114     public GLONASSAlmanac(final int channel, final int health,
115                           final int day, final int month, final int year,
116                           final double ta, final double lambda,
117                           final double deltaI, final double pa,
118                           final double ecc, final double deltaT, final double deltaTDot,
119                           final double tGlo2UTC, final double tGPS2Glo, final double tGlo) {
120         this(channel, health, day, month, year, ta, lambda, deltaI, pa, ecc, deltaT,
121                 deltaTDot, tGlo2UTC, tGPS2Glo, tGlo,
122                 DataContext.getDefault().getTimeScales().getGLONASS());
123     }
124 
125     /**
126      * Constructor.
127      *
128      * @param channel the frequency channel from -7 to 6)
129      * @param health the Health status
130      * @param day the day of Almanac
131      * @param month the month of Almanac
132      * @param year the year of Almanac
133      * @param ta the reference time of the almanac (s)
134      * @param lambda the Greenwich longitude of ascending node of orbit (rad)
135      * @param deltaI the correction to the mean value of inclination (rad)
136      * @param pa the argument of perigee (rad)
137      * @param ecc the eccentricity
138      * @param deltaT the correction to the mean value of Draconian period (s)
139      * @param deltaTDot the rate of change of orbital period
140      * @param tGlo2UTC the correction from GLONASS to UTC (s)
141      * @param tGPS2Glo the correction to GPS time relative GLONASS (s)
142      * @param tGlo the correction of time relative to GLONASS system time (s)
143      * @param glonass GLONASS time scale.
144      * @since 10.1
145      */
146     public GLONASSAlmanac(final int channel, final int health,
147                           final int day, final int month, final int year,
148                           final double ta, final double lambda,
149                           final double deltaI, final double pa,
150                           final double ecc, final double deltaT, final double deltaTDot,
151                           final double tGlo2UTC, final double tGPS2Glo, final double tGlo,
152                           final TimeScale glonass) {
153         this.channel = channel;
154         this.health = health;
155         this.day = day;
156         this.month = month;
157         this.year = year;
158         this.ta = ta;
159         this.lambda = lambda;
160         this.deltaI = deltaI;
161         this.pa = pa;
162         this.ecc = ecc;
163         this.deltaT = deltaT;
164         this.deltaTDot = deltaTDot;
165         this.tGlo2UTC = tGlo2UTC;
166         this.tGPS2Glo = tGPS2Glo;
167         this.tGlo = tGlo;
168         this.glonass = glonass;
169     }
170 
171     /**
172      * Get the propagator corresponding to the navigation message.
173      * <p>
174      * The attitude provider is set by default to be aligned with the EME2000 frame.<br>
175      * The mass is set by default to the
176      *  {@link org.orekit.propagation.Propagator#DEFAULT_MASS DEFAULT_MASS}.<br>
177      * The data context is by default to the
178      *  {@link DataContext#getDefault() default data context}.<br>
179      * The ECI frame is set by default to the
180      *  {@link org.orekit.frames.Predefined#EME2000 EME2000 frame} in the default data
181      *  context.<br>
182      * The ECEF frame is set by default to the
183      *  {@link org.orekit.frames.Predefined#ITRF_CIO_CONV_2010_SIMPLE_EOP
184      *  CIO/2010-based ITRF simple EOP} in the default data context.
185      * </p>
186      * @return the propagator corresponding to the navigation message
187      * @see #getPropagator(DataContext)
188      * @see #getPropagator(DataContext, AttitudeProvider, Frame, Frame, double)
189      * @since 12.0
190      */
191     @DefaultDataContext
192     public GLONASSAnalyticalPropagator getPropagator() {
193         return new GLONASSAnalyticalPropagatorBuilder(this).build();
194     }
195 
196     /**
197      * Get the propagator corresponding to the navigation message.
198      * <p>
199      * The attitude provider is set by default to be aligned with the EME2000 frame.<br>
200      * The mass is set by default to the
201      *  {@link org.orekit.propagation.Propagator#DEFAULT_MASS DEFAULT_MASS}.<br>
202      * The ECI frame is set by default to the
203      *  {@link Frames#getEME2000() EME2000 frame}.<br>
204      * The ECEF frame is set by default to the
205      *  {@link Frames#getITRF(IERSConventions, boolean) CIO/2010-based ITRF simple
206      *  EOP}.
207      * </p>
208      * @param context the data context to use for frames and time scales.
209      * @return the propagator corresponding to the navigation message
210      * @see #getPropagator()
211      * @see #getPropagator(DataContext, AttitudeProvider, Frame, Frame, double)
212      * @since 12.0
213      */
214     public GLONASSAnalyticalPropagator getPropagator(final DataContext context) {
215         return new GLONASSAnalyticalPropagatorBuilder(this, context).build();
216     }
217 
218     /**
219      * Get the propagator corresponding to the navigation message.
220      * @param context the data context to use for frames and time scales.
221      * @param provider attitude provider
222      * @param inertial inertial frame, use to provide the propagated orbit
223      * @param bodyFixed body fixed frame, corresponding to the navigation message
224      * @param mass spacecraft mass in kg
225      * @return the propagator corresponding to the navigation message
226      * @see #getPropagator()
227      * @see #getPropagator(DataContext)
228      * @since 12.0
229      */
230     public GLONASSAnalyticalPropagator getPropagator(final DataContext context, final AttitudeProvider provider,
231                                                      final Frame inertial, final Frame bodyFixed,
232                                                      final double mass) {
233         return new GLONASSAnalyticalPropagatorBuilder(this, context).attitudeProvider(provider)
234                                                                     .eci(inertial)
235                                                                     .ecef(bodyFixed)
236                                                                     .mass(mass)
237                                                                     .build();
238     }
239 
240     @Override
241     public AbsoluteDate getDate() {
242         final DateComponents date = new DateComponents(year, month, day);
243         final TimeComponents time = new TimeComponents(ta);
244         return new AbsoluteDate(date, time, glonass);
245     }
246 
247     @Override
248     public double getTime() {
249         return ta;
250     }
251 
252     @Override
253     public double getLambda() {
254         return lambda;
255     }
256 
257     @Override
258     public double getE() {
259         return ecc;
260     }
261 
262     @Override
263     public double getPa() {
264         return pa;
265     }
266 
267     @Override
268     public double getDeltaI() {
269         return deltaI;
270     }
271 
272     @Override
273     public double getDeltaT() {
274         return deltaT;
275     }
276 
277     @Override
278     public double getDeltaTDot() {
279         return deltaTDot;
280     }
281 
282     /**
283      * Get the Health status.
284      *
285      * @return the Health status
286      */
287     public int getHealth() {
288         return health;
289     }
290 
291     /**
292      * Get the frequency channel.
293      *
294      * @return the frequency channel
295      */
296     public int getFrequencyChannel() {
297         return channel;
298     }
299 
300     /**
301      * Get the correction from GLONASS to UTC.
302      *
303      * @return the correction from GLONASS to UTC (s)
304      */
305     public double getGlo2UTC() {
306         return tGlo2UTC;
307     }
308 
309     /**
310      * Get the correction to GPS time relative GLONASS.
311      *
312      * @return the to GPS time relative GLONASS (s)
313      */
314     public double getGPS2Glo() {
315         return tGPS2Glo;
316     }
317 
318     /**
319      * Get the correction of time relative to GLONASS system time.
320      *
321      * @return the correction of time relative to GLONASS system time (s)
322      */
323     public double getGloOffset() {
324         return tGlo;
325     }
326 
327     @Override
328     public int getNa() {
329         final GLONASSDate gloDate = new GLONASSDate(getDate(), glonass);
330         return gloDate.getDayNumber();
331     }
332 
333     @Override
334     public int getN4() {
335         final GLONASSDate gloDate = new GLONASSDate(getDate(), glonass);
336         return gloDate.getIntervalNumber();
337     }
338 }