1 /* Copyright 2022-2025 Luc Maisonobe
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.util.FastMath;
20 import org.orekit.gnss.SatelliteSystem;
21 import org.orekit.time.AbsoluteDate;
22 import org.orekit.time.GNSSDate;
23 import org.orekit.time.TimeScales;
24 import org.orekit.utils.ParameterDriver;
25 import org.orekit.utils.ParameterDriversProvider;
26 import org.orekit.utils.ParameterObserver;
27 import org.orekit.utils.TimeSpanMap;
28
29 import java.util.Arrays;
30 import java.util.List;
31
32 /** This class manages the non-keplerian parameter drivers for
33 * {@link GNSSOrbitalElements} and {@link FieldGnssOrbitalElements}.
34 * <p>
35 * In both primitive double and field classes, only the non-Keplerian parameters
36 * are returned in the {@link #getParametersDrivers()} method, the Keplerian orbital
37 * parameters must be accessed independently. These groups ensure proper separate
38 * computation of state transition matrix and Jacobian matrix by
39 * {@link org.orekit.propagation.analytical.gnss.GNSSPropagator} and
40 * {@link org.orekit.propagation.analytical.gnss.FieldGnssPropagator}.
41 * </p>
42 * @since 13.0
43 * @author Luc Maisonobe
44 */
45 public abstract class GNSSOrbitalElementsDriversProvider
46 implements ParameterDriversProvider {
47
48 /** Name for time parameter. */
49 public static final String TIME = "GnssTime";
50
51 /** Name for inclination rate parameter. */
52 public static final String INCLINATION_RATE = "GnssInclinationRate";
53
54 /** Name for longitude rate parameter. */
55 public static final String LONGITUDE_RATE = "GnssLongitudeRate";
56
57 /** Name for cosine of latitude argument harmonic parameter. */
58 public static final String LATITUDE_COSINE = "GnssLatitudeCosine";
59
60 /** Name for sine of latitude argument harmonic parameter. */
61 public static final String LATITUDE_SINE = "GnssLatitudeSine";
62
63 /** Name for cosine of orbit radius harmonic parameter. */
64 public static final String RADIUS_COSINE = "GnssRadiusCosine";
65
66 /** Name for sine of orbit radius harmonic parameter. */
67 public static final String RADIUS_SINE = "GnssRadiusSine";
68
69 /** Name for cosine of inclination harmonic parameter. */
70 public static final String INCLINATION_COSINE = "GnssInclinationCosine";
71
72 /** Name for sine of inclination harmonic parameter. */
73 public static final String INCLINATION_SINE = "GnssInclinationSine";
74
75 /** Index of time in the list returned by {@link #getParametersDrivers()}. */
76 public static final int TIME_INDEX = 0;
77
78 /** Index of inclination rate in the list returned by {@link #getParametersDrivers()}. */
79 public static final int I_DOT_INDEX = TIME_INDEX + 1;
80
81 /** Index of longitude rate in the list returned by {@link #getParametersDrivers()}. */
82 public static final int OMEGA_DOT_INDEX = I_DOT_INDEX + 1;
83
84 /** Index of cosine on latitude argument in the list returned by {@link #getParametersDrivers()}. */
85 public static final int CUC_INDEX = OMEGA_DOT_INDEX + 1;
86
87 /** Index of sine on latitude argument in the list returned by {@link #getParametersDrivers()}. */
88 public static final int CUS_INDEX = CUC_INDEX + 1;
89
90 /** Index of cosine on radius in the list returned by {@link #getParametersDrivers()}. */
91 public static final int CRC_INDEX = CUS_INDEX + 1;
92
93 /** Index of sine on radius in the list returned by {@link #getParametersDrivers()}. */
94 public static final int CRS_INDEX = CRC_INDEX + 1;
95
96 /** Index of cosine on inclination in the list returned by {@link #getParametersDrivers()}. */
97 public static final int CIC_INDEX = CRS_INDEX + 1;
98
99 /** Index of sine on inclination in the list returned by {@link #getParametersDrivers()}. */
100 public static final int CIS_INDEX = CIC_INDEX + 1;
101
102 /** Size of parameters array. */
103 public static final int SIZE = CIS_INDEX + 1;
104
105 /** Mean angular velocity of the Earth for the GNSS model. */
106 private final double angularVelocity;
107
108 /** Duration of the GNSS cycle in weeks. */
109 private final int weeksInCycle;
110
111 /** Duration of the GNSS cycle in seconds. */
112 private final double cycleDuration;
113
114 /** Satellite system to use for interpreting week number. */
115 private final SatelliteSystem system;
116
117 /** Known time scales. */
118 private final TimeScales timeScales;
119
120 /** PRN number of the satellite. */
121 private int prn;
122
123 /** Reference Week of the orbit. */
124 private int week;
125
126 /** Reference time. */
127 private final ParameterDriver timeDriver;
128
129 /** Inclination rate (rad/s). */
130 private final ParameterDriver iDotDriver;
131
132 /** Rate of right ascension (rad/s). */
133 private final ParameterDriver domDriver;
134
135 /** Amplitude of the cosine harmonic correction term to the argument of latitude. */
136 private final ParameterDriver cucDriver;
137
138 /** Amplitude of the sine harmonic correction term to the argument of latitude. */
139 private final ParameterDriver cusDriver;
140
141 /** Amplitude of the cosine harmonic correction term to the orbit radius. */
142 private final ParameterDriver crcDriver;
143
144 /** Amplitude of the sine harmonic correction term to the orbit radius. */
145 private final ParameterDriver crsDriver;
146
147 /** Amplitude of the cosine harmonic correction term to the inclination. */
148 private final ParameterDriver cicDriver;
149
150 /** Amplitude of the sine harmonic correction term to the inclination. */
151 private final ParameterDriver cisDriver;
152
153 /** Constructor.
154 * @param angularVelocity mean angular velocity of the Earth for the GNSS model
155 * @param weeksInCycle number of weeks in the GNSS cycle
156 * @param timeScales known time scales
157 * @param system satellite system to consider for interpreting week number
158 * (may be different from real system, for example in Rinex nav, weeks
159 * are always according to GPS)
160 */
161 protected GNSSOrbitalElementsDriversProvider(final double angularVelocity, final int weeksInCycle,
162 final TimeScales timeScales, final SatelliteSystem system) {
163
164 // immutable fields
165 this.angularVelocity = angularVelocity;
166 this.weeksInCycle = weeksInCycle;
167 this.cycleDuration = GNSSConstants.GNSS_WEEK_IN_SECONDS * weeksInCycle;
168 this.system = system;
169 this.timeScales = timeScales;
170
171 this.timeDriver = createDriver(TIME);
172 this.iDotDriver = createDriver(INCLINATION_RATE);
173 this.domDriver = createDriver(LONGITUDE_RATE);
174 this.cucDriver = createDriver(LATITUDE_COSINE);
175 this.cusDriver = createDriver(LATITUDE_SINE);
176 this.crcDriver = createDriver(RADIUS_COSINE);
177 this.crsDriver = createDriver(RADIUS_SINE);
178 this.cicDriver = createDriver(INCLINATION_COSINE);
179 this.cisDriver = createDriver(INCLINATION_SINE);
180
181 // automatically update date when time driver is updated
182 timeDriver.addObserver(new ParameterObserver() {
183
184 /** {@inheritDoc} */
185 @Override
186 public void valueChanged(final double previousValue, final ParameterDriver driver,
187 final AbsoluteDate date) {
188 setGnssDate(new GNSSDate(week, driver.getValue(), system, timeScales));
189 }
190
191 /** {@inheritDoc} */
192 @Override
193 public void valueSpanMapChanged(final TimeSpanMap<Double> previousValueSpanMap,
194 final ParameterDriver driver) {
195 // nothing to do
196 }
197 });
198
199 }
200
201 /** Copy drivers selection settings from another instance.
202 * @param original original instance providing selection settings
203 */
204 protected void copySelectionSettings(final GNSSOrbitalElementsDriversProvider original) {
205 timeDriver.setSelected(original.timeDriver.isSelected());
206 iDotDriver.setSelected(original.iDotDriver.isSelected());
207 domDriver.setSelected(original.domDriver.isSelected());
208 cucDriver.setSelected(original.cucDriver.isSelected());
209 cusDriver.setSelected(original.cusDriver.isSelected());
210 crcDriver.setSelected(original.crcDriver.isSelected());
211 crsDriver.setSelected(original.crsDriver.isSelected());
212 cicDriver.setSelected(original.cicDriver.isSelected());
213 cisDriver.setSelected(original.cisDriver.isSelected());
214 }
215
216 /** Set GNSS date.
217 * @param gnssDate GNSS date
218 */
219 protected abstract void setGnssDate(GNSSDate gnssDate);
220
221 /** Create parameter driver.
222 * @param name name of the driver
223 * @return build driver
224 */
225 protected static ParameterDriver createDriver(final String name) {
226 return new ParameterDriver(name, 0, FastMath.scalb(1.0, -30),
227 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
228 }
229
230 /** Get satellite system.
231 * @return satellite system
232 */
233 public SatelliteSystem getSystem() {
234 return system;
235 }
236
237 /** Get known time scales.
238 * @return known time scales
239 */
240 public TimeScales getTimeScales() {
241 return timeScales;
242 }
243
244 /** {@inheritDoc}
245 * <p>
246 * Only the 9 non-Keplerian evolution parameters are listed here,
247 * i.e. {@link #getTimeDriver()} (at index {@link #TIME_INDEX}),
248 * {@link #getIDotDriver()} (at index {@link #I_DOT_INDEX}),
249 * {@link #getOmegaDotDriver()} (at index {@link #OMEGA_DOT_INDEX}),
250 * {@link #getCucDriver()} (at index {@link #CUC_INDEX}),
251 * {@link #getCusDriver()} (at index {@link #CUS_INDEX}),
252 * {@link #getCrcDriver()} (at index {@link #CRC_INDEX}),
253 * {@link #getCrsDriver()} (at index {@link #CRS_INDEX}),
254 * {@link #getCicDriver()} (at index {@link #CIC_INDEX}),
255 * and {@link #getCisDriver()} (at index {@link #CIS_INDEX})
256 * </p>
257 * <p>
258 * The Keplerian orbital parameters drivers are not included.
259 * </p>
260 */
261 @Override
262 public List<ParameterDriver> getParametersDrivers() {
263 // ensure the parameters are really at the advertised indices
264 final ParameterDriver[] array = new ParameterDriver[SIZE];
265 array[TIME_INDEX] = getTimeDriver();
266 array[I_DOT_INDEX] = getIDotDriver();
267 array[OMEGA_DOT_INDEX] = getOmegaDotDriver();
268 array[CUC_INDEX] = getCucDriver();
269 array[CUS_INDEX] = getCusDriver();
270 array[CRC_INDEX] = getCrcDriver();
271 array[CRS_INDEX] = getCrsDriver();
272 array[CIC_INDEX] = getCicDriver();
273 array[CIS_INDEX] = getCisDriver();
274 return Arrays.asList(array);
275 }
276
277 /** Get the mean angular velocity of the Earth of the GNSS model.
278 * @return mean angular velocity of the Earth of the GNSS model
279 */
280 public double getAngularVelocity() {
281 return angularVelocity;
282 }
283
284 /** Get for the duration of the GNSS cycle in weeks.
285 * @return the duration of the GNSS cycle in weeks
286 */
287 public int getWeeksInCycle() {
288 return weeksInCycle;
289 }
290
291 /** Get for the duration of the GNSS cycle in seconds.
292 * @return the duration of the GNSS cycle in seconds
293 */
294 public double getCycleDuration() {
295 return cycleDuration;
296 }
297
298 /** Get the PRN number of the satellite.
299 * @return PRN number of the satellite
300 */
301 public int getPRN() {
302 return prn;
303 }
304
305 /** Set the PRN number of the satellite.
306 * @param number the prn number ot set
307 */
308 public void setPRN(final int number) {
309 this.prn = number;
310 }
311
312 /** Get the reference week of the orbit.
313 * @return reference week of the orbit
314 */
315 public int getWeek() {
316 return week;
317 }
318
319 /** Set the reference week of the orbit.
320 * @param week the week to set
321 */
322 public void setWeek(final int week) {
323 this.week = week;
324 setGnssDate(new GNSSDate(week, timeDriver.getValue(), system, timeScales));
325 }
326
327 /** Get the driver for reference time of the GNSS orbit as a duration from week start.
328 * @return driver for the reference time of the GNSS orbit (s)
329 */
330 public ParameterDriver getTimeDriver() {
331 return timeDriver;
332 }
333
334 /** Get reference time of the GNSS orbit as a duration from week start.
335 * @return reference time of the GNSS orbit (s)
336 */
337 public double getTime() {
338 return getTimeDriver().getValue();
339 }
340
341 /** Set reference time of the GNSS orbit as a duration from week start.
342 * @param time reference time of the GNSS orbit (s)
343 */
344 public void setTime(final double time) {
345 getTimeDriver().setValue(time);
346 }
347
348 /** Get the driver for the rate of inclination angle.
349 * @return driver for the rate of inclination angle (rad/s)
350 */
351 public ParameterDriver getIDotDriver() {
352 return iDotDriver;
353 }
354
355 /** Get rate of inclination angle.
356 * @return rate of inclination angle (rad/s)
357 */
358 public double getIDot() {
359 return getIDotDriver().getValue();
360 }
361
362 /** Set the driver for the rate of inclination angle.
363 * @param iDot rate of inclination angle (rad/s)
364 */
365 public void setIDot(final double iDot) {
366 getIDotDriver().setValue(iDot);
367 }
368
369 /** Get the driver for the rate of right ascension.
370 * @return driver for the rate of right ascension (rad/s)
371 */
372 public ParameterDriver getOmegaDotDriver() {
373 return domDriver;
374 }
375
376 /** Get rate of right ascension.
377 * @return rate of right ascension (rad/s)
378 */
379 public double getOmegaDot() {
380 return getOmegaDotDriver().getValue();
381 }
382
383 /** Set rate of right ascension.
384 * @param dom rate of right ascension (rad/s)
385 */
386 public void setOmegaDot(final double dom) {
387 getOmegaDotDriver().setValue(dom);
388 }
389
390 /** Get the driver for the amplitude of the cosine harmonic correction term to the argument of latitude.
391 * @return driver for the amplitude of the cosine harmonic correction term to the argument of latitude (rad)
392 */
393 public ParameterDriver getCucDriver() {
394 return cucDriver;
395 }
396
397 /** Get amplitude of the cosine harmonic correction term to the argument of latitude.
398 * @return amplitude of the cosine harmonic correction term to the argument of latitude (rad)
399 */
400 public double getCuc() {
401 return getCucDriver().getValue();
402 }
403
404 /** Set amplitude of the cosine harmonic correction term to the argument of latitude.
405 * @param cuc amplitude of the cosine harmonic correction term to the argument of latitude (rad)
406 */
407 public void setCuc(final double cuc) {
408 getCucDriver().setValue(cuc);
409 }
410
411 /** Get the driver for the amplitude of the sine harmonic correction term to the argument of latitude.
412 * @return driver for the amplitude of the sine harmonic correction term to the argument of latitude (rad)
413 */
414 public ParameterDriver getCusDriver() {
415 return cusDriver;
416 }
417
418 /** Get amplitude of the sine harmonic correction term to the argument of latitude.
419 * @return amplitude of the sine harmonic correction term to the argument of latitude (rad)
420 */
421 public double getCus() {
422 return getCusDriver().getValue();
423 }
424
425 /** Set amplitude of the sine harmonic correction term to the argument of latitude.
426 * @param cus amplitude of the sine harmonic correction term to the argument of latitude (rad)
427 */
428 public void setCus(final double cus) {
429 getCusDriver().setValue(cus);
430 }
431
432 /** Get the driver for the amplitude of the cosine harmonic correction term to the orbit radius.
433 * @return driver for the amplitude of the cosine harmonic correction term to the orbit radius (m)
434 */
435 public ParameterDriver getCrcDriver() {
436 return crcDriver;
437 }
438
439 /** Get amplitude of the cosine harmonic correction term to the orbit radius.
440 * @return amplitude of the cosine harmonic correction term to the orbit radius (m)
441 */
442 public double getCrc() {
443 return getCrcDriver().getValue();
444 }
445
446 /** Set amplitude of the cosine harmonic correction term to the orbit radius.
447 * @param crc amplitude of the cosine harmonic correction term to the orbit radius (m)
448 */
449 public void setCrc(final double crc) {
450 getCrcDriver().setValue(crc);
451 }
452
453 /** Get the driver for the amplitude of the sine harmonic correction term to the orbit radius.
454 * @return driver for the amplitude of the sine harmonic correction term to the orbit radius (m)
455 */
456 public ParameterDriver getCrsDriver() {
457 return crsDriver;
458 }
459
460 /** Get amplitude of the sine harmonic correction term to the orbit radius.
461 * @return amplitude of the sine harmonic correction term to the orbit radius (m)
462 */
463 public double getCrs() {
464 return getCrsDriver().getValue();
465 }
466
467 /** Set amplitude of the sine harmonic correction term to the orbit radius.
468 * @param crs amplitude of the sine harmonic correction term to the orbit radius (m)
469 */
470 public void setCrs(final double crs) {
471 getCrsDriver().setValue(crs);
472 }
473
474 /** Get the driver for the amplitude of the cosine harmonic correction term to the angle of inclination.
475 * @return driver for the amplitude of the cosine harmonic correction term to the angle of inclination (rad)
476 */
477 public ParameterDriver getCicDriver() {
478 return cicDriver;
479 }
480
481 /** Get amplitude of the cosine harmonic correction term to the angle of inclination.
482 * @return amplitude of the cosine harmonic correction term to the angle of inclination (rad)
483 */
484 public double getCic() {
485 return getCicDriver().getValue();
486 }
487
488 /** Set amplitude of the cosine harmonic correction term to the angle of inclination.
489 * @param cic amplitude of the cosine harmonic correction term to the angle of inclination (rad)
490 */
491 public void setCic(final double cic) {
492 getCicDriver().setValue(cic);
493 }
494
495 /** Get the driver for the amplitude of the sine harmonic correction term to the angle of inclination.
496 * @return driver for the amplitude of the sine harmonic correction term to the angle of inclination (rad)
497 */
498 public ParameterDriver getCisDriver() {
499 return cisDriver;
500 }
501
502 /** Get amplitude of the sine harmonic correction term to the angle of inclination.
503 * @return amplitude of the sine harmonic correction term to the angle of inclination (rad)
504 */
505 public double getCis() {
506 return getCisDriver().getValue();
507 }
508
509 /** Set amplitude of the sine harmonic correction term to the angle of inclination.
510 * @param cis amplitude of the sine harmonic correction term to the angle of inclination (rad)
511 */
512 public void setCis(final double cis) {
513 getCisDriver().setValue(cis);
514 }
515
516 }