1 /* Copyright 2002-2024 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.estimation.measurements.modifiers;
18
19 import java.util.List;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.Field;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.orekit.estimation.measurements.GroundStation;
26 import org.orekit.models.earth.troposphere.TroposphericModel;
27 import org.orekit.propagation.FieldSpacecraftState;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.utils.FieldTrackingCoordinates;
30 import org.orekit.utils.ParameterDriver;
31 import org.orekit.utils.TrackingCoordinates;
32
33 /** Baselass modifying theoretical range-rate measurements with tropospheric delay.
34 * The effect of tropospheric correction on the range-rate is directly computed
35 * through the computation of the tropospheric delay difference with respect to
36 * time.
37 *
38 * In general, for GNSS, VLBI, ... there is hardly any frequency dependence in the delay.
39 * For SLR techniques however, the frequency dependence is sensitive.
40 *
41 * @author Joris Olympio
42 * @since 11.2
43 */
44 public abstract class BaseRangeRateTroposphericDelayModifier {
45
46 /** Tropospheric delay model. */
47 private final TroposphericModel tropoModel;
48
49 /** Constructor.
50 *
51 * @param model Tropospheric delay model appropriate for the current range-rate measurement method.
52 * @deprecated as of 12.1, replaced by {@link #BaseRangeRateTroposphericDelayModifier(TroposphericModel)}
53 */
54 @Deprecated
55 protected BaseRangeRateTroposphericDelayModifier(final org.orekit.models.earth.troposphere.DiscreteTroposphericModel model) {
56 this(new org.orekit.models.earth.troposphere.TroposphericModelAdapter(model));
57 }
58
59 /** Constructor.
60 *
61 * @param model Tropospheric delay model appropriate for the current range-rate measurement method.
62 * @since 12.1
63 */
64 protected BaseRangeRateTroposphericDelayModifier(final TroposphericModel model) {
65 tropoModel = model;
66 }
67
68 /** Get the tropospheric delay model.
69 * @return tropospheric delay model
70 */
71 protected TroposphericModel getTropoModel() {
72 return tropoModel;
73 }
74
75 /** Compute the measurement error due to Troposphere.
76 * @param station station
77 * @param state spacecraft state
78 * @return the measurement error due to Troposphere
79 */
80 public double rangeRateErrorTroposphericModel(final GroundStation station,
81 final SpacecraftState state) {
82 // The effect of tropospheric correction on the range rate is
83 // computed using finite differences.
84
85 final double dt = 10; // s
86
87 // spacecraft position and elevation as seen from the ground station
88 final Vector3D position = state.getPosition();
89
90 // tracking
91 final TrackingCoordinates trackingCoordinates1 =
92 station.getBaseFrame().getTrackingCoordinates(position, state.getFrame(), state.getDate());
93
94 // only consider measures above the horizon
95 if (trackingCoordinates1.getElevation() > 0) {
96 // tropospheric delay in meters
97 final double d1 = tropoModel.pathDelay(trackingCoordinates1,
98 station.getOffsetGeodeticPoint(state.getDate()),
99 station.getPressureTemperatureHumidity(state.getDate()),
100 tropoModel.getParameters(state.getDate()), state.getDate()).
101 getDelay();
102
103 // propagate spacecraft state forward by dt
104 final SpacecraftState state2 = state.shiftedBy(dt);
105
106 // spacecraft position and elevation as seen from the ground station
107 final Vector3D position2 = state2.getPosition();
108
109 // tracking
110 final TrackingCoordinates trackingCoordinates2 =
111 station.getBaseFrame().getTrackingCoordinates(position2, state2.getFrame(), state2.getDate());
112
113 // tropospheric delay dt after
114 final double d2 = tropoModel.pathDelay(trackingCoordinates2,
115 station.getOffsetGeodeticPoint(state.getDate()),
116 station.getPressureTemperatureHumidity(state.getDate()),
117 tropoModel.getParameters(state2.getDate()), state2.getDate()).
118 getDelay();
119
120 return (d2 - d1) / dt;
121 }
122
123 return 0;
124 }
125
126
127 /** Compute the measurement error due to Troposphere.
128 * @param <T> type of the element
129 * @param station station
130 * @param state spacecraft state
131 * @param parameters tropospheric model parameters
132 * @return the measurement error due to Troposphere
133 */
134 public <T extends CalculusFieldElement<T>> T rangeRateErrorTroposphericModel(final GroundStation station,
135 final FieldSpacecraftState<T> state,
136 final T[] parameters) {
137 // Field
138 final Field<T> field = state.getDate().getField();
139 final T zero = field.getZero();
140
141 // The effect of tropospheric correction on the range rate is
142 // computed using finite differences.
143
144 final double dt = 10; // s
145
146 // spacecraft position and elevation as seen from the ground station
147 final FieldVector3D<T> position = state.getPosition();
148 final FieldTrackingCoordinates<T> trackingCoordinates1 =
149 station.getBaseFrame().getTrackingCoordinates(position, state.getFrame(), state.getDate());
150
151 // only consider measures above the horizon
152 if (trackingCoordinates1.getElevation().getReal() > 0) {
153 // tropospheric delay in meters
154 final T d1 = tropoModel.pathDelay(trackingCoordinates1,
155 station.getOffsetGeodeticPoint(state.getDate()),
156 station.getPressureTemperatureHumidity(state.getDate()),
157 parameters, state.getDate()).
158 getDelay();
159
160 // propagate spacecraft state forward by dt
161 final FieldSpacecraftState<T> state2 = state.shiftedBy(dt);
162
163 // spacecraft position and elevation as seen from the ground station
164 final FieldVector3D<T> position2 = state2.getPosition();
165
166 // elevation
167 final FieldTrackingCoordinates<T> trackingCoordinates2 =
168 station.getBaseFrame().getTrackingCoordinates(position2, state2.getFrame(), state2.getDate());
169
170
171 // tropospheric delay dt after
172 final T d2 = tropoModel.pathDelay(trackingCoordinates2,
173 station.getOffsetGeodeticPoint(state.getDate()),
174 station.getPressureTemperatureHumidity(state.getDate()),
175 parameters, state2.getDate()).
176 getDelay();
177
178 return d2.subtract(d1).divide(dt);
179 }
180
181 return zero;
182 }
183
184 /** Get the drivers for this modifier parameters.
185 * @return drivers for this modifier parameters
186 */
187 public List<ParameterDriver> getParametersDrivers() {
188 return tropoModel.getParametersDrivers();
189 }
190
191 }