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