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.numerical;
18  
19  import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
20  import org.orekit.annotation.DefaultDataContext;
21  import org.orekit.attitudes.AttitudeProvider;
22  import org.orekit.attitudes.FrameAlignedProvider;
23  import org.orekit.data.DataContext;
24  import org.orekit.frames.Frame;
25  import org.orekit.propagation.Propagator;
26  import org.orekit.propagation.analytical.gnss.data.GLONASSAlmanac;
27  import org.orekit.propagation.analytical.gnss.data.GLONASSFdmaNavigationMessage;
28  import org.orekit.propagation.analytical.gnss.data.GLONASSOrbitalElements;
29  
30  /**
31   * This nested class aims at building a GLONASSNumericalPropagator.
32   * <p>It implements the classical builder pattern.</p>
33   * <p>
34   * <b>Caution:</b> The Glonass numerical propagator can only be used with {@link GLONASSFdmaNavigationMessage}.
35   * Using this propagator with a {@link GLONASSAlmanac} is prone to error.
36   * </p>
37   * @author Bryan Cazabonne
38   * @since 11.0
39   */
40  public class GLONASSNumericalPropagatorBuilder {
41  
42      //////////
43      // Required parameter
44      //////////
45  
46      /** The GLONASS orbital elements. */
47      private final GLONASSOrbitalElements orbit;
48  
49      /** The 4th order Runge-Kutta integrator. */
50      private final ClassicalRungeKuttaIntegrator integrator;
51  
52      /** Flag for availability of projections of acceleration transmitted within the navigation message. */
53      private final boolean isAccAvailable;
54  
55      ///////////
56      // Optional parameters
57      //////////
58  
59      /** The attitude provider. */
60      private AttitudeProvider attitudeProvider;
61  
62      /** The mass. */
63      private double mass;
64  
65      /** The ECI frame. */
66      private Frame eci;
67  
68      /** Data context for the propagator. */
69      private final DataContext dataContext;
70  
71      /**
72       * Initializes the builder.
73       * <p>The attitude provider is set by default to EME2000 aligned in the
74       *  default data context.<br>
75       * The mass is set by default to the
76       *  {@link org.orekit.propagation.Propagator#DEFAULT_MASS DEFAULT_MASS}.<br>
77       * The data context is by default to the
78       *  {@link DataContext#getDefault() default data context}.<br>
79       * The ECI frame is set by default to the
80       *  {@link org.orekit.frames.Predefined#EME2000 EME2000 frame} in the default data
81       *  context.<br>
82       * </p>
83       *
84       * @param integrator 4th order Runge-Kutta as recommended by GLONASS ICD
85       * @param glonassOrbElt the GLONASS orbital elements to be used by the GLONASSNumericalPropagator.
86       * @param isAccAvailable flag for availability of the projections of accelerations transmitted within
87       *        the navigation message
88       * @see #attitudeProvider(AttitudeProvider provider)
89       * @see #mass(double mass)
90       * @see #eci(Frame inertial)
91       */
92      @DefaultDataContext
93      public GLONASSNumericalPropagatorBuilder(final ClassicalRungeKuttaIntegrator integrator,
94                                               final GLONASSOrbitalElements glonassOrbElt,
95                                               final boolean isAccAvailable) {
96          this(integrator, glonassOrbElt, isAccAvailable, DataContext.getDefault());
97      }
98  
99  
100     /**
101      * Initializes the builder.
102      * <p>The attitude provider is set by default to EME2000 aligned in the
103      *  provided data context.<br>
104      * The mass is set by default to the
105      *  {@link org.orekit.propagation.Propagator#DEFAULT_MASS DEFAULT_MASS}.<br>
106      * The ECI frame is set by default to the
107      *  {@link org.orekit.frames.Predefined#EME2000 EME2000 frame} in the default data
108      *  context.<br>
109      * </p>
110      *
111      * @param integrator 4th order Runge-Kutta as recommended by GLONASS ICD
112      * @param glonassOrbElt the GLONASS orbital elements to be used by the GLONASSNumericalPropagator.
113      * @param isAccAvailable flag for availability of the projections of accelerations transmitted within
114      *        the navigation message
115      * @param context data context
116      * @see #attitudeProvider(AttitudeProvider provider)
117      * @see #mass(double mass)
118      * @see #eci(Frame inertial)
119      */
120     public GLONASSNumericalPropagatorBuilder(final ClassicalRungeKuttaIntegrator integrator,
121                                              final GLONASSOrbitalElements glonassOrbElt,
122                                              final boolean isAccAvailable,
123                                              final DataContext context) {
124         this.isAccAvailable   = isAccAvailable;
125         this.integrator       = integrator;
126         this.orbit            = glonassOrbElt;
127         this.mass             = Propagator.DEFAULT_MASS;
128         this.dataContext      = context;
129         this.eci              = dataContext.getFrames().getEME2000();
130         this.attitudeProvider = FrameAlignedProvider.of(this.eci);
131     }
132 
133     /**
134      * Sets the attitude provider.
135      *
136      * @param userProvider the attitude provider
137      * @return the updated builder
138      */
139     public GLONASSNumericalPropagatorBuilder attitudeProvider(final AttitudeProvider userProvider) {
140         this.attitudeProvider = userProvider;
141         return this;
142     }
143 
144     /**
145      * Sets the mass.
146      *
147      * @param userMass the mass (in kg)
148      * @return the updated builder
149      */
150     public GLONASSNumericalPropagatorBuilder mass(final double userMass) {
151         this.mass = userMass;
152         return this;
153     }
154 
155     /**
156      * Sets the Earth Centered Inertial frame used for propagation.
157      *
158      * @param inertial the ECI frame
159      * @return the updated builder
160      */
161     public GLONASSNumericalPropagatorBuilder eci(final Frame inertial) {
162         this.eci = inertial;
163         return this;
164     }
165 
166     /**
167      * Finalizes the build.
168      *
169      * @return the built Glonass numerical propagator
170      */
171     public GLONASSNumericalPropagator build() {
172         return new GLONASSNumericalPropagator(integrator, orbit, eci, attitudeProvider,
173                                               mass, dataContext, isAccAvailable);
174     }
175 
176 }