1 /* Copyright 2002-2026 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, 0);
110 this.eccDriver = createDriver(ECCENTRICITY, -24);
111 this.i0Driver = createDriver(INCLINATION, -24);
112 this.aopDriver = createDriver(ARGUMENT_OF_PERIGEE, -24);
113 this.om0Driver = createDriver(NODE_LONGITUDE, -24);
114 this.anomDriver = createDriver(MEAN_ANOMALY, -24);
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-Keplerian parameters
129 copyNonKeplerian(original);
130
131 // Keplerian orbital elements
132 setSma(original.getSma().getReal());
133 setE(original.getE().getReal());
134 setI0(original.getI0().getReal());
135 setPa(original.getPa().getReal());
136 setOmega0(original.getOmega0().getReal());
137 setM0(original.getM0().getReal());
138
139 // copy selection settings
140 copySelectionSettings(original);
141
142 }
143
144 /** Create a field version of the instance.
145 * @param <T> type of the field elements
146 * @param <F> type of the orbital elements (field version)
147 * @param field field to which elements belong
148 * @return field version of the instance
149 */
150 public abstract <T extends CalculusFieldElement<T>, F extends FieldGnssOrbitalElements<T, O>>
151 F toField(Field<T> field);
152
153 /** {@inheritDoc} */
154 protected void setGnssDate(final GNSSDate gnssDate) {
155 this.date = gnssDate.getDate();
156 }
157
158 /** {@inheritDoc} */
159 @Override
160 public AbsoluteDate getDate() {
161 return date;
162 }
163
164 /** Get the Earth's universal gravitational parameter.
165 * @return the Earth's universal gravitational parameter
166 */
167 public double getMu() {
168 return mu;
169 }
170
171 /** Get semi-major axis.
172 * @return driver for the semi-major axis (m)
173 */
174 public ParameterDriver getSmaDriver() {
175 return smaDriver;
176 }
177
178 /** Get semi-major axis.
179 * @return semi-major axis (m)
180 */
181 public double getSma() {
182 return getSmaDriver().getValue();
183 }
184
185 /** Set semi-major axis.
186 * @param sma demi-major axis (m)
187 */
188 public void setSma(final double sma) {
189 getSmaDriver().setValue(sma);
190 }
191
192 /** Get the computed mean motion n₀.
193 * @return the computed mean motion n₀ (rad/s)
194 * @since 13.0
195 */
196 public double getMeanMotion0() {
197 final double absA = FastMath.abs(getSma());
198 return FastMath.sqrt(getMu() / absA) / absA;
199 }
200
201 /** Get the driver for the eccentricity.
202 * @return driver for the eccentricity
203 */
204 public ParameterDriver getEDriver() {
205 return eccDriver;
206 }
207
208 /** Get eccentricity.
209 * @return eccentricity
210 */
211 public double getE() {
212 return getEDriver().getValue();
213 }
214
215 /** Set eccentricity.
216 * @param e eccentricity
217 */
218 public void setE(final double e) {
219 getEDriver().setValue(e);
220 }
221
222 /** Get the driver for the inclination angle at reference time.
223 * @return driver for the inclination angle at reference time (rad)
224 */
225 public ParameterDriver getI0Driver() {
226 return i0Driver;
227 }
228
229 /** Get the inclination angle at reference time.
230 * @return inclination angle at reference time (rad)
231 */
232 public double getI0() {
233 return getI0Driver().getValue();
234 }
235
236 /** Set inclination angle at reference time.
237 * @param i0 inclination angle at reference time (rad)
238 */
239 public void setI0(final double i0) {
240 getI0Driver().setValue(i0);
241 }
242
243 /** Get the driver for the longitude of ascending node of orbit plane at weekly epoch.
244 * @return driver for the longitude of ascending node of orbit plane at weekly epoch (rad)
245 */
246 public ParameterDriver getOmega0Driver() {
247 return om0Driver;
248 }
249
250 /** Get longitude of ascending node of orbit plane at weekly epoch.
251 * @return longitude of ascending node of orbit plane at weekly epoch (rad)
252 */
253 public double getOmega0() {
254 return getOmega0Driver().getValue();
255 }
256
257 /** Set longitude of ascending node of orbit plane at weekly epoch.
258 * @param om0 longitude of ascending node of orbit plane at weekly epoch (rad)
259 */
260 public void setOmega0(final double om0) {
261 getOmega0Driver().setValue(om0);
262 }
263
264 /** Get the driver for the argument of perigee.
265 * @return driver for the argument of perigee (rad)
266 */
267 public ParameterDriver getPaDriver() {
268 return aopDriver;
269 }
270
271 /** Get argument of perigee.
272 * @return argument of perigee (rad)
273 */
274 public double getPa() {
275 return getPaDriver().getValue();
276 }
277
278 /** Set argument of perigee.
279 * @param aop argument of perigee (rad)
280 */
281 public void setPa(final double aop) {
282 getPaDriver().setValue(aop);
283 }
284
285 /** Get the driver for the mean anomaly at reference time.
286 * @return driver for the mean anomaly at reference time (rad)
287 */
288 public ParameterDriver getM0Driver() {
289 return anomDriver;
290 }
291
292 /** Get mean anomaly at reference time.
293 * @return mean anomaly at reference time (rad)
294 */
295 public double getM0() {
296 return getM0Driver().getValue();
297 }
298
299 /** Set mean anomaly at reference time.
300 * @param anom mean anomaly at reference time (rad)
301 */
302 public void setM0(final double anom) {
303 getM0Driver().setValue(anom);
304 }
305
306 }