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;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.orekit.propagation.AdditionalDataProvider;
21 import org.orekit.propagation.SpacecraftState;
22 import org.orekit.propagation.analytical.gnss.data.GNSSClockElements;
23 import org.orekit.time.AbsoluteDate;
24 import org.orekit.utils.Constants;
25 import org.orekit.utils.PVCoordinates;
26
27 /** Provider for clock corrections as additional states.
28 * <p>
29 * The value of this additional state is a three elements array containing
30 * </p>
31 * <ul>
32 * <li>at index 0, the polynomial satellite clock model
33 * Δtₛₐₜ = {@link GNSSClockElements#getAf0() a₀} +
34 * {@link GNSSClockElements#getAf1() a₁} (t - {@link GNSSClockElements#getToc() toc}) +
35 * {@link GNSSClockElements#getAf1() a₂} (t - {@link GNSSClockElements#getToc() toc})²
36 * </li>
37 * <li>at index 1 the relativistic clock correction due to eccentricity</li>
38 * <li>at index 2 the estimated group delay differential {@link GNSSClockElements#getTGD() TGD} for L1-L2 correction</li>
39 * </ul>
40 * <p>
41 * Since Orekit 10.3 the relativistic clock correction can be used as an
42 * {@link org.orekit.estimation.measurements.EstimationModifier} in orbit determination applications
43 * to take into consideration this effect in measurement modeling.
44 * </p>
45 *
46 * @author Luc Maisonobe
47 * @since 9.3
48 */
49 public class ClockCorrectionsProvider implements AdditionalDataProvider<double[]> {
50
51 /** Name of the additional state for satellite clock corrections.
52 * @since 9.3
53 */
54 public static final String CLOCK_CORRECTIONS = "";
55
56 /** The GPS clock elements. */
57 private final GNSSClockElements gnssClk;
58
59 /** Clock reference epoch. */
60 private final AbsoluteDate clockRef;
61
62 /** Duration of the GNSS cycle in seconds. */
63 private final double cycleDuration;
64
65 /** Simple constructor.
66 * @param gnssClk GNSS clock elements
67 * @param cycleDuration duration of the GNSS cycle in seconds
68 */
69 public ClockCorrectionsProvider(final GNSSClockElements gnssClk,
70 final double cycleDuration) {
71 this.gnssClk = gnssClk;
72 this.clockRef = gnssClk.getDate();
73 this.cycleDuration = cycleDuration;
74 }
75
76 /** {@inheritDoc} */
77 @Override
78 public String getName() {
79 return CLOCK_CORRECTIONS;
80 }
81
82 /**
83 * Get the duration from clock Reference epoch.
84 * <p>This takes the GNSS week roll-over into account.</p>
85 *
86 * @param date the considered date
87 * @return the duration from clock Reference epoch (s)
88 */
89 private double getDT(final AbsoluteDate date) {
90 // Time from ephemeris reference epoch
91 double dt = date.durationFrom(clockRef);
92 // Adjusts the time to take roll over week into account
93 while (dt > 0.5 * cycleDuration) {
94 dt -= cycleDuration;
95 }
96 while (dt < -0.5 * cycleDuration) {
97 dt += cycleDuration;
98 }
99 // Returns the time from ephemeris reference epoch
100 return dt;
101 }
102
103 /** {@inheritDoc} */
104 @Override
105 public double[] getAdditionalData(final SpacecraftState state) {
106
107 // polynomial clock model
108 final double dt = getDT(state.getDate());
109 final double dtSat = gnssClk.getAf0() + dt * (gnssClk.getAf1() + dt * gnssClk.getAf2());
110
111 // relativistic effect due to eccentricity
112 final PVCoordinates pv = state.getPVCoordinates();
113 final double dtRel = -2 * Vector3D.dotProduct(pv.getPosition(), pv.getVelocity()) /
114 (Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT);
115
116 // estimated group delay differential
117 final double tg = gnssClk.getTGD();
118
119 return new double[] {
120 dtSat, dtRel, tg
121 };
122 }
123
124 }