1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.attitudes.FrameAlignedProvider;
26 import org.orekit.estimation.measurements.EstimatedMeasurement;
27 import org.orekit.estimation.measurements.EstimatedMeasurementBase;
28 import org.orekit.estimation.measurements.EstimationModifier;
29 import org.orekit.estimation.measurements.GroundStation;
30 import org.orekit.estimation.measurements.TDOA;
31 import org.orekit.models.earth.troposphere.TroposphericModel;
32 import org.orekit.propagation.FieldSpacecraftState;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.utils.Constants;
35 import org.orekit.utils.FieldTrackingCoordinates;
36 import org.orekit.utils.ParameterDriver;
37 import org.orekit.utils.TrackingCoordinates;
38
39
40
41
42
43
44
45
46
47
48
49 public class TDOATroposphericDelayModifier implements EstimationModifier<TDOA> {
50
51
52 private final TroposphericModel tropoModel;
53
54
55
56
57
58
59 public TDOATroposphericDelayModifier(final TroposphericModel model) {
60 tropoModel = model;
61 }
62
63
64 @Override
65 public String getEffectName() {
66 return "troposphere";
67 }
68
69
70
71
72
73
74 private double timeErrorTroposphericModel(final GroundStation station, final SpacecraftState state) {
75 final Vector3D position = state.getPosition();
76
77
78 final TrackingCoordinates trackingCoordinates =
79 station.getBaseFrame().getTrackingCoordinates(position, state.getFrame(), state.getDate());
80
81
82 if (trackingCoordinates.getElevation() > 0) {
83
84 final double delay = tropoModel.pathDelay(trackingCoordinates,
85 station.getOffsetGeodeticPoint(state.getDate()),
86 tropoModel.getParameters(state.getDate()), state.getDate()).
87 getDelay();
88
89 return delay / Constants.SPEED_OF_LIGHT;
90 }
91
92 return 0;
93 }
94
95
96
97
98
99
100
101
102 private <T extends CalculusFieldElement<T>> T timeErrorTroposphericModel(final GroundStation station,
103 final FieldSpacecraftState<T> state,
104 final T[] parameters) {
105
106 final Field<T> field = state.getDate().getField();
107 final T zero = field.getZero();
108
109
110 final FieldVector3D<T> pos = state.getPosition();
111 final FieldTrackingCoordinates<T> trackingCoordinates =
112 station.getBaseFrame().getTrackingCoordinates(pos, state.getFrame(), state.getDate());
113
114
115 if (trackingCoordinates.getElevation().getReal() > 0) {
116
117 final T delay = tropoModel.pathDelay(trackingCoordinates,
118 station.getOffsetGeodeticPoint(state.getDate()),
119 parameters, state.getDate()).
120 getDelay();
121
122 return delay.divide(Constants.SPEED_OF_LIGHT);
123 }
124
125 return zero;
126 }
127
128
129 @Override
130 public List<ParameterDriver> getParametersDrivers() {
131 return tropoModel.getParametersDrivers();
132 }
133
134
135 @Override
136 public void modifyWithoutDerivatives(final EstimatedMeasurementBase<TDOA> estimated) {
137
138 final TDOA measurement = estimated.getObservedMeasurement();
139 final GroundStation primeStation = measurement.getPrimeStation();
140 final GroundStation secondStation = measurement.getSecondStation();
141
142 TDOAModifierUtil.modifyWithoutDerivatives(estimated, primeStation, secondStation,
143 this::timeErrorTroposphericModel, this);
144
145 }
146
147
148 @Override
149 public void modify(final EstimatedMeasurement<TDOA> estimated) {
150
151 final TDOA measurement = estimated.getObservedMeasurement();
152 final GroundStation primeStation = measurement.getPrimeStation();
153 final GroundStation secondStation = measurement.getSecondStation();
154 final SpacecraftState state = estimated.getStates()[0];
155
156 TDOAModifierUtil.modify(estimated, tropoModel,
157 new ModifierGradientConverter(state, 6, new FrameAlignedProvider(state.getFrame())),
158 primeStation, secondStation,
159 this::timeErrorTroposphericModel,
160 this::timeErrorTroposphericModel,
161 this);
162
163 }
164
165 }