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 }