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.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
20 import org.hipparchus.util.FastMath;
21 import org.orekit.annotation.DefaultDataContext;
22 import org.orekit.attitudes.AttitudeProvider;
23 import org.orekit.data.DataContext;
24 import org.orekit.frames.Frame;
25 import org.orekit.propagation.numerical.GLONASSNumericalPropagator;
26 import org.orekit.propagation.numerical.GLONASSNumericalPropagatorBuilder;
27
28 /**
29 * Container for data contained in a Glonass FDMA navigation message.
30 * @author Bryan Cazabonne
31 * @since 11.0
32 */
33 public class GLONASSFdmaNavigationMessage extends AbstractEphemerisMessage implements GLONASSOrbitalElements {
34
35 /** Message type.
36 * @since 14.0
37 */
38 public static final String FDMA = "FDMA";
39
40 /** Message frame time. */
41 private double time;
42
43 /** SV clock bias. */
44 private double tauN;
45
46 /** SV relative frequency bias. */
47 private double gammaN;
48
49 /** Frequency number. */
50 private int frequencyNumber;
51
52 /** Status flags.
53 * @since 12.0
54 */
55 private int statusFlags;
56
57 /** Health flags.
58 * @since 12.0
59 */
60 private int healthFlags;
61
62 /** Group Delay Difference (s).
63 * @since 12.0
64 */
65 private double groupDelayDifference;
66
67 /** User range accuracy (m).
68 * @since 12.0
69 */
70 private double ura;
71
72 /** Constructor. */
73 public GLONASSFdmaNavigationMessage() {
74 // Nothing to do ...
75 }
76
77 /** {@inheritDoc} */
78 @Override
79 public String getNavigationMessageType() {
80 return FDMA;
81 }
82
83 /** {@inheritDoc} */
84 @Override
85 public String getNavigationMessageSubType() {
86 return null;
87 }
88
89 /**
90 * Get the propagator corresponding to the navigation message.
91 * <p>The attitude provider is set by default to EME2000 aligned in the
92 * default data context.<br>
93 * The mass is set by default to the
94 * {@link org.orekit.propagation.Propagator#DEFAULT_MASS DEFAULT_MASS}.<br>
95 * The data context is by default to the
96 * {@link DataContext#getDefault() default data context}.<br>
97 * The ECI frame is set by default to the
98 * {@link org.orekit.frames.Predefined#EME2000 EME2000 frame} in the default data
99 * context.<br>
100 * </p>
101 * @param step integration step in seconds
102 * @return the propagator corresponding to the navigation message
103 * @see #getPropagator(double, DataContext)
104 * @see #getPropagator(double, DataContext, AttitudeProvider, Frame, double)
105 * @since 12.0
106 */
107 @DefaultDataContext
108 public GLONASSNumericalPropagator getPropagator(final double step) {
109 return new GLONASSNumericalPropagatorBuilder(new ClassicalRungeKuttaIntegrator(step),
110 this, isAccAvailable()).build();
111 }
112
113 /**
114 * Get the propagator corresponding to the navigation message.
115 * <p>The attitude provider is set by default to EME2000 aligned in the
116 * default data context.<br>
117 * The mass is set by default to the
118 * {@link org.orekit.propagation.Propagator#DEFAULT_MASS DEFAULT_MASS}.<br>
119 * The data context is by default to the
120 * {@link DataContext#getDefault() default data context}.<br>
121 * The ECI frame is set by default to the
122 * {@link org.orekit.frames.Predefined#EME2000 EME2000 frame} in the default data
123 * context.<br>
124 * </p>
125 * @param step integration step in seconds
126 * @param context data context
127 * @return the propagator corresponding to the navigation message
128 * @see #getPropagator(double)
129 * @see #getPropagator(double, DataContext, AttitudeProvider, Frame, double)
130 * @since 12.0
131 */
132 public GLONASSNumericalPropagator getPropagator(final double step, final DataContext context) {
133 return new GLONASSNumericalPropagatorBuilder(new ClassicalRungeKuttaIntegrator(step),
134 this, isAccAvailable(), context).build();
135 }
136
137 /**
138 * Get the propagator corresponding to the navigation message.
139 * @param step integration step in seconds
140 * @param context data context
141 * @param provider attitude provider
142 * @param inertial inertial frame, use to provide the propagated orbit
143 * @param mass spacecraft mass in kg
144 * @return the propagator corresponding to the navigation message
145 * @see #getPropagator(double)
146 * @see #getPropagator(double, DataContext)
147 * @since 12.0
148 */
149 public GLONASSNumericalPropagator getPropagator(final double step, final DataContext context,
150 final AttitudeProvider provider, final Frame inertial,
151 final double mass) {
152 return new GLONASSNumericalPropagatorBuilder(new ClassicalRungeKuttaIntegrator(step),
153 this, isAccAvailable(), context).attitudeProvider(provider)
154 .eci(inertial)
155 .mass(mass)
156 .build();
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 public double getTN() {
162 return tauN;
163 }
164
165 /**
166 * Setter for the SV clock bias.
167 * @param tn the SV clock bias
168 */
169 public void setTauN(final double tn) {
170 this.tauN = tn;
171 }
172
173 /** {@inheritDoc} */
174 @Override
175 public double getGammaN() {
176 return gammaN;
177 }
178
179 /**
180 * Setter for the SV relative frequency bias.
181 * @param gammaN the SV relative frequency bias.
182 */
183 public void setGammaN(final double gammaN) {
184 this.gammaN = gammaN;
185 }
186
187 /**
188 * Getter for the frequency number.
189 * @return the frequency number
190 */
191 public int getFrequencyNumber() {
192 return frequencyNumber;
193 }
194
195 /**
196 * Setter for the frequency number.
197 * @param frequencyNumber the number to set
198 */
199 public void setFrequencyNumber(final double frequencyNumber) {
200 this.frequencyNumber = (int) frequencyNumber;
201 }
202
203 /** {@inheritDoc} */
204 @Override
205 public double getTime() {
206 return time;
207 }
208
209 /**
210 * Setter for the message frame time.
211 * @param time the time to set
212 */
213 public void setTime(final double time) {
214 this.time = time;
215 }
216
217 /** Get status flags.
218 * @return status flags
219 * @since 12.0
220 */
221 public int getStatusFlags() {
222 return statusFlags;
223 }
224
225 /** Set status flag.
226 * @param statusFlags status flag (parsed as a double)
227 * @since 12.0
228 */
229 public void setStatusFlags(final double statusFlags) {
230 this.statusFlags = (int) FastMath.rint(statusFlags);
231 }
232
233 /** Set health flag.
234 * @param healthFlags health flag (parsed as a double)
235 * @since 12.0
236 */
237 public void setHealthFlags(final double healthFlags) {
238 this.healthFlags = Double.isNaN(healthFlags) ? 15 : (int) FastMath.rint(healthFlags);
239 }
240
241 /** Get health flags.
242 * @return health flags
243 * @since 12.0
244 */
245 public int getHealthFlags() {
246 return healthFlags;
247 }
248
249 /** Get group delay difference.
250 * @return group delay difference
251 * @since 12.0
252 */
253 public double getGroupDelayDifference() {
254 return groupDelayDifference;
255 }
256
257 /** Set group delay difference.
258 * @param groupDelayDifference group delay difference
259 * @since 12.0
260 */
261 public void setGroupDelayDifference(final double groupDelayDifference) {
262 this.groupDelayDifference = Double.isNaN(groupDelayDifference) ?
263 0.999999999999e+09 :
264 groupDelayDifference;
265 }
266
267 /**
268 * Getter for the user range accuray (meters).
269 * @return the user range accuracy
270 * @since 12.0
271 */
272 public double getURA() {
273 return ura;
274 }
275
276 /**
277 * Setter for the user range accuracy.
278 * @param accuracy the value to set
279 * @since 12.0
280 */
281 public void setURA(final double accuracy) {
282 this.ura = accuracy;
283 }
284
285 /**
286 * Check if the acceleration is available in the navigation message.
287 * @return true if the acceleration is available
288 */
289 private boolean isAccAvailable() {
290 return getXDotDot() != 0.0 || getYDotDot() != 0.0 || getZDotDot() != 0.0;
291 }
292
293 }