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 org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.MathUtils;
21 import org.orekit.estimation.measurements.AngularAzEl;
22 import org.orekit.estimation.measurements.EstimatedMeasurementBase;
23 import org.orekit.estimation.measurements.EstimationModifier;
24 import org.orekit.estimation.measurements.GroundStation;
25 import org.orekit.frames.Frame;
26 import org.orekit.models.earth.troposphere.TroposphericModel;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.time.AbsoluteDate;
29 import org.orekit.utils.Constants;
30 import org.orekit.utils.ParameterDriver;
31 import org.orekit.utils.TrackingCoordinates;
32
33 import java.util.List;
34
35 /** Class modifying theoretical angular measurement with tropospheric delay.
36 * <p>
37 * The effect of tropospheric correction on the angular is computed
38 * through the computation of the tropospheric delay.The spacecraft state
39 * is shifted by the computed delay time and elevation and azimuth are computed
40 * again with the new spacecraft state.
41 * </p>
42 * <p>
43 * In general, for GNSS, VLBI, ... there is hardly any frequency dependence in the delay.
44 * For SLR techniques however, the frequency dependence is sensitive.
45 * </p>
46 * @deprecated as of 12.1, {@link AngularRadioRefractionModifier} shall be used to handle tropospheric effect on angular measurements
47 * @author Thierry Ceolin
48 * @since 8.0
49 */
50 @Deprecated
51 public class AngularTroposphericDelayModifier implements EstimationModifier<AngularAzEl> {
52
53 /** Tropospheric delay model. */
54 private final TroposphericModel tropoModel;
55
56 /** Constructor.
57 *
58 * @param model Tropospheric delay model appropriate for the current angular measurement method.
59 * @deprecated as of 12.1, {@link AngularRadioRefractionModifier} shall be used to handle tropospheric effect on angular measurements
60 */
61 @Deprecated
62 public AngularTroposphericDelayModifier(final org.orekit.models.earth.troposphere.DiscreteTroposphericModel model) {
63 this(new org.orekit.models.earth.troposphere.TroposphericModelAdapter(model));
64 }
65
66 /** Constructor.
67 *
68 * @param model Tropospheric delay model appropriate for the current angular measurement method.
69 * @since 12.1
70 * @deprecated as of 12.1, {@link AngularRadioRefractionModifier} shall be used to handle tropospheric effect on angular measurements
71 */
72 @Deprecated
73 public AngularTroposphericDelayModifier(final TroposphericModel model) {
74 tropoModel = model;
75 }
76
77 /** Compute the measurement error due to Troposphere.
78 * @param station station
79 * @param state spacecraft state
80 * @return the measurement error due to Troposphere
81 */
82 private double angularErrorTroposphericModel(final GroundStation station,
83 final SpacecraftState state) {
84 //
85 final Vector3D position = state.getPosition();
86
87 // tracking
88 final TrackingCoordinates trackingCoordinates =
89 station.getBaseFrame().getTrackingCoordinates(position, state.getFrame(), state.getDate());
90
91 // only consider measures above the horizon
92 if (trackingCoordinates.getElevation() > 0.0) {
93 // delay in meters
94 return tropoModel.pathDelay(trackingCoordinates,
95 station.getOffsetGeodeticPoint(state.getDate()),
96 station.getPressureTemperatureHumidity(state.getDate()),
97 tropoModel.getParameters(state.getDate()), state.getDate()).
98 getDelay();
99
100 }
101
102 return 0;
103 }
104
105 /** {@inheritDoc} */
106 @Override
107 public List<ParameterDriver> getParametersDrivers() {
108 return tropoModel.getParametersDrivers();
109 }
110
111 @Override
112 public void modifyWithoutDerivatives(final EstimatedMeasurementBase<AngularAzEl> estimated) {
113 final AngularAzEl measure = estimated.getObservedMeasurement();
114 final GroundStation station = measure.getStation();
115 final SpacecraftState state = estimated.getStates()[0];
116
117 final double delay = angularErrorTroposphericModel(station, state);
118 // Delay is taken into account to shift the spacecraft position
119 final double dt = delay / Constants.SPEED_OF_LIGHT;
120
121 // Position of the spacecraft shifted of dt
122 final SpacecraftState transitState = state.shiftedBy(-dt);
123
124 // Update measurement value taking into account the ionospheric delay.
125 final AbsoluteDate date = transitState.getDate();
126 final Vector3D position = transitState.getPosition();
127 final Frame inertial = transitState.getFrame();
128
129 // Elevation and azimuth in radians
130 final TrackingCoordinates tc = station.getBaseFrame().getTrackingCoordinates(position, inertial, date);
131 final double twoPiWrap = MathUtils.normalizeAngle(tc.getAzimuth(), measure.getObservedValue()[0]) - tc.getAzimuth();
132 final double azimuth = tc.getAzimuth() + twoPiWrap;
133
134 // Update estimated value taking into account the tropospheric delay.
135 // Azimuth - elevation values
136 estimated.modifyEstimatedValue(this, azimuth, tc.getElevation());
137 }
138
139 }