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.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.util.FastMath;
22 import org.orekit.gnss.SatelliteSystem;
23 import org.orekit.propagation.analytical.gnss.GNSSPropagator;
24 import org.orekit.time.AbsoluteDate;
25 import org.orekit.time.GNSSDate;
26 import org.orekit.time.TimeScales;
27 import org.orekit.time.TimeStamped;
28 import org.orekit.utils.ParameterDriver;
29
30 /** This class provides the minimal set of orbital elements needed by the {@link GNSSPropagator}.
31 * <p>
32 * The parameters are split in two groups: Keplerian orbital parameters and non-Keplerian
33 * evolution parameters. All parameters can be updated as they are all instances of
34 * {@link ParameterDriver}. Only the non-Keplerian parameters are returned in the
35 * {@link #getParametersDrivers()} method, the Keplerian orbital parameters must
36 * be accessed independently. These groups ensure proper separate computation of
37 * state transition matrix and Jacobian matrix by {@link GNSSPropagator}.
38 * </p>
39 * @param <O> type of the orbital elements
40 * @since 13.0
41 * @author Pascal Parraud
42 * @author Luc Maisonobe
43 */
44 public abstract class GNSSOrbitalElements<O extends GNSSOrbitalElements<O>>
45 extends GNSSOrbitalElementsDriversProvider
46 implements TimeStamped {
47
48 /** Name for semi major axis parameter. */
49 public static final String SEMI_MAJOR_AXIS = "GnssSemiMajorAxis";
50
51 /** Name for eccentricity parameter. */
52 public static final String ECCENTRICITY = "GnssEccentricity";
53
54 /** Name for inclination at reference time parameter. */
55 public static final String INCLINATION = "GnssInclination";
56
57 /** Name for argument of perigee parameter. */
58 public static final String ARGUMENT_OF_PERIGEE = "GnssPerigeeArgument";
59
60 /** Name for longitude of ascending node at weekly epoch parameter. */
61 public static final String NODE_LONGITUDE = "GnssNodeLongitude";
62
63 /** Name for mean anomaly at reference time parameter. */
64 public static final String MEAN_ANOMALY = "GnssMeanAnomaly";
65
66 /** Earth's universal gravitational parameter. */
67 private final double mu;
68
69 /** Reference epoch. */
70 private AbsoluteDate date;
71
72 /** Semi-Major Axis (m). */
73 private final ParameterDriver smaDriver;
74
75 /** Eccentricity. */
76 private final ParameterDriver eccDriver;
77
78 /** Inclination angle at reference time (rad). */
79 private final ParameterDriver i0Driver;
80
81 /** Argument of perigee (rad). */
82 private final ParameterDriver aopDriver;
83
84 /** Longitude of ascending node of orbit plane at weekly epoch (rad). */
85 private final ParameterDriver om0Driver;
86
87 /** Mean anomaly at reference time (rad). */
88 private final ParameterDriver anomDriver;
89
90 /**
91 * Constructor.
92 * @param mu Earth's universal gravitational parameter
93 * @param angularVelocity mean angular velocity of the Earth for the GNSS model
94 * @param weeksInCycle number of weeks in the GNSS cycle
95 * @param timeScales known time scales
96 * @param system satellite system to consider for interpreting week number
97 * (may be different from real system, for example in Rinex nav, weeks
98 * are always according to GPS)
99 */
100 protected GNSSOrbitalElements(final double mu, final double angularVelocity, final int weeksInCycle,
101 final TimeScales timeScales, final SatelliteSystem system) {
102
103 super(angularVelocity, weeksInCycle, timeScales, system);
104
105 // immutable field
106 this.mu = mu;
107
108 // fields controlled by parameter drivers for Keplerian orbital elements
109 this.smaDriver = createDriver(SEMI_MAJOR_AXIS);
110 this.eccDriver = createDriver(ECCENTRICITY);
111 this.i0Driver = createDriver(INCLINATION);
112 this.aopDriver = createDriver(ARGUMENT_OF_PERIGEE);
113 this.om0Driver = createDriver(NODE_LONGITUDE);
114 this.anomDriver = createDriver(MEAN_ANOMALY);
115
116 }
117
118 /** Constructor from field instance.
119 * @param <T> type of the field elements
120 * @param <A> type of the orbital elements (non-field version)
121 * @param original regular field instance
122 */
123 protected <T extends CalculusFieldElement<T>,
124 A extends GNSSOrbitalElements<A>> GNSSOrbitalElements(final FieldGnssOrbitalElements<T, A> original) {
125 this(original.getMu().getReal(), original.getAngularVelocity(), original.getWeeksInCycle(),
126 original.getTimeScales(), original.getSystem());
127
128 // non-Keperian parameters
129 setPRN(original.getPRN());
130 setWeek(original.getWeek());
131 setTime(original.getTime());
132 setIDot(original.getIDot());
133 setOmegaDot(original.getOmegaDot());
134 setCuc(original.getCuc());
135 setCus(original.getCus());
136 setCrc(original.getCrc());
137 setCrs(original.getCrs());
138 setCic(original.getCic());
139 setCis(original.getCis());
140
141 // Keplerian orbital elements
142 setSma(original.getSma().getReal());
143 setE(original.getE().getReal());
144 setI0(original.getI0().getReal());
145 setPa(original.getPa().getReal());
146 setOmega0(original.getOmega0().getReal());
147 setM0(original.getM0().getReal());
148
149 // copy selection settings
150 copySelectionSettings(original);
151
152 }
153
154 /** Create a field version of the instance.
155 * @param <T> type of the field elements
156 * @param <F> type of the orbital elements (field version)
157 * @param field field to which elements belong
158 * @return field version of the instance
159 */
160 public abstract <T extends CalculusFieldElement<T>, F extends FieldGnssOrbitalElements<T, O>>
161 F toField(Field<T> field);
162
163 /** {@inheritDoc} */
164 protected void setGnssDate(final GNSSDate gnssDate) {
165 this.date = gnssDate.getDate();
166 }
167
168 /** {@inheritDoc} */
169 @Override
170 public AbsoluteDate getDate() {
171 return date;
172 }
173
174 /** Get the Earth's universal gravitational parameter.
175 * @return the Earth's universal gravitational parameter
176 */
177 public double getMu() {
178 return mu;
179 }
180
181 /** Get semi-major axis.
182 * @return driver for the semi-major axis (m)
183 */
184 public ParameterDriver getSmaDriver() {
185 return smaDriver;
186 }
187
188 /** Get semi-major axis.
189 * @return semi-major axis (m)
190 */
191 public double getSma() {
192 return getSmaDriver().getValue();
193 }
194
195 /** Set semi-major axis.
196 * @param sma demi-major axis (m)
197 */
198 public void setSma(final double sma) {
199 getSmaDriver().setValue(sma);
200 }
201
202 /** Getter for the change rate in semi-major axis.
203 * <p>
204 * This value is non-zero only in civilian navigation messages
205 * </p>
206 * @return the change rate in semi-major axis
207 * @since 13.0
208 */
209 public double getADot() {
210 return 0;
211 }
212
213 /** Get the computed mean motion n₀.
214 * @return the computed mean motion n₀ (rad/s)
215 * @since 13.0
216 */
217 public double getMeanMotion0() {
218 final double absA = FastMath.abs(getSma());
219 return FastMath.sqrt(getMu() / absA) / absA;
220 }
221
222 /** Getter for the delta of satellite mean motion.
223 * <p>
224 * This value is non-zero only in navigation messages
225 * </p>
226 * @return delta of satellite mean motion
227 * @since 13.0
228 */
229 public double getDeltaN0() {
230 return 0;
231 }
232
233 /** Getter for change rate in Δn₀.
234 * <p>
235 * This value is non-zero only in civilian navigation messages
236 * </p>
237 * @return change rate in Δn₀
238 * @since 13.0
239 */
240 public double getDeltaN0Dot() {
241 return 0;
242 }
243
244 /** Get the driver for the eccentricity.
245 * @return driver for the eccentricity
246 */
247 public ParameterDriver getEDriver() {
248 return eccDriver;
249 }
250
251 /** Get eccentricity.
252 * @return eccentricity
253 */
254 public double getE() {
255 return getEDriver().getValue();
256 }
257
258 /** Set eccentricity.
259 * @param e eccentricity
260 */
261 public void setE(final double e) {
262 getEDriver().setValue(e);
263 }
264
265 /** Get the driver for the inclination angle at reference time.
266 * @return driver for the inclination angle at reference time (rad)
267 */
268 public ParameterDriver getI0Driver() {
269 return i0Driver;
270 }
271
272 /** Get the inclination angle at reference time.
273 * @return inclination angle at reference time (rad)
274 */
275 public double getI0() {
276 return getI0Driver().getValue();
277 }
278
279 /** Set inclination angle at reference time.
280 * @param i0 inclination angle at reference time (rad)
281 */
282 public void setI0(final double i0) {
283 getI0Driver().setValue(i0);
284 }
285
286 /** Get the driver for the longitude of ascending node of orbit plane at weekly epoch.
287 * @return driver for the longitude of ascending node of orbit plane at weekly epoch (rad)
288 */
289 public ParameterDriver getOmega0Driver() {
290 return om0Driver;
291 }
292
293 /** Get longitude of ascending node of orbit plane at weekly epoch.
294 * @return longitude of ascending node of orbit plane at weekly epoch (rad)
295 */
296 public double getOmega0() {
297 return getOmega0Driver().getValue();
298 }
299
300 /** Set longitude of ascending node of orbit plane at weekly epoch.
301 * @param om0 longitude of ascending node of orbit plane at weekly epoch (rad)
302 */
303 public void setOmega0(final double om0) {
304 getOmega0Driver().setValue(om0);
305 }
306
307 /** Get the driver for the argument of perigee.
308 * @return driver for the argument of perigee (rad)
309 */
310 public ParameterDriver getPaDriver() {
311 return aopDriver;
312 }
313
314 /** Get argument of perigee.
315 * @return argument of perigee (rad)
316 */
317 public double getPa() {
318 return getPaDriver().getValue();
319 }
320
321 /** Set argument of perigee.
322 * @param aop argument of perigee (rad)
323 */
324 public void setPa(final double aop) {
325 getPaDriver().setValue(aop);
326 }
327
328 /** Get the driver for the mean anomaly at reference time.
329 * @return driver for the mean anomaly at reference time (rad)
330 */
331 public ParameterDriver getM0Driver() {
332 return anomDriver;
333 }
334
335 /** Get mean anomaly at reference time.
336 * @return mean anomaly at reference time (rad)
337 */
338 public double getM0() {
339 return getM0Driver().getValue();
340 }
341
342 /** Set mean anomaly at reference time.
343 * @param anom mean anomaly at reference time (rad)
344 */
345 public void setM0(final double anom) {
346 getM0Driver().setValue(anom);
347 }
348
349 }