1 /* Copyright 2002-2021 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.models.earth.ionosphere;
18
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.hipparchus.util.FastMath;
26 import org.orekit.frames.TopocentricFrame;
27 import org.orekit.propagation.FieldSpacecraftState;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.utils.ParameterDriver;
30
31 /**
32 * An estimated ionospheric model. The ionospheric delay is computed according to the formula:
33 * <p>
34 * 40.3
35 * δ = -------- * STEC with, STEC = VTEC * F(elevation)
36 * f²
37 * </p>
38 * With:
39 * <ul>
40 * <li>f: The frequency of the signal in Hz.</li>
41 * <li>STEC: The Slant Total Electron Content in TECUnits.</li>
42 * <li>VTEC: The Vertical Total Electron Content in TECUnits.</li>
43 * <li>F(elevation): A mapping function which depends on satellite elevation.</li>
44 * </ul>
45 * The VTEC is estimated as a {@link ParameterDriver}
46 *
47 * @author Bryan Cazabonne
48 * @since 10.2
49 */
50 public class EstimatedIonosphericModel implements IonosphericModel {
51
52 /** Name of the parameter of this model: the Vertical Total Electron Content. */
53 public static final String VERTICAL_TOTAL_ELECTRON_CONTENT = "vertical total electron content";
54
55 /** Serializable UID. */
56 private static final long serialVersionUID = 20200304L;
57
58 /** Ionospheric delay factor. */
59 private static final double FACTOR = 40.3e16;
60
61 /** Ionospheric mapping Function model. */
62 private final transient IonosphericMappingFunction model;
63
64 /** Driver for the Vertical Total Electron Content.*/
65 private final transient ParameterDriver vtec;
66
67
68 /**
69 * Build a new instance.
70 * @param model ionospheric mapping function
71 * @param vtecValue value of the Vertical Total Electron Content in TECUnits
72 */
73 public EstimatedIonosphericModel(final IonosphericMappingFunction model, final double vtecValue) {
74 this.model = model;
75 this.vtec = new ParameterDriver(EstimatedIonosphericModel.VERTICAL_TOTAL_ELECTRON_CONTENT,
76 vtecValue, FastMath.scalb(1.0, 3), 0.0, 1000.0);
77 }
78
79 /** {@inheritDoc} */
80 @Override
81 public double pathDelay(final SpacecraftState state, final TopocentricFrame baseFrame,
82 final double frequency, final double[] parameters) {
83 // Elevation in radians
84 final Vector3D position = state.getPVCoordinates(baseFrame).getPosition();
85 final double elevation = position.getDelta();
86
87 // Only consider measures above the horizon
88 if (elevation > 0.0) {
89 // Delay
90 return pathDelay(elevation, frequency, parameters);
91 }
92
93 return 0.0;
94 }
95
96 /**
97 * Calculates the ionospheric path delay for the signal path from a ground
98 * station to a satellite.
99 * <p>
100 * The path delay is computed for any elevation angle.
101 * </p>
102 * @param elevation elevation of the satellite in radians
103 * @param frequency frequency of the signal in Hz
104 * @param parameters ionospheric model parameters
105 * @return the path delay due to the ionosphere in m
106 */
107 public double pathDelay(final double elevation, final double frequency, final double[] parameters) {
108 // Square of the frequency
109 final double freq2 = frequency * frequency;
110 // Mapping factor
111 final double fz = model.mappingFactor(elevation);
112 // "Slant" Total Electron Content
113 final double stec = parameters[0] * fz;
114 // Delay computation
115 final double alpha = FACTOR / freq2;
116 return alpha * stec;
117 }
118
119 /** {@inheritDoc} */
120 @Override
121 public <T extends CalculusFieldElement<T>> T pathDelay(final FieldSpacecraftState<T> state, final TopocentricFrame baseFrame,
122 final double frequency, final T[] parameters) {
123 // Elevation and azimuth in radians
124 final FieldVector3D<T> position = state.getPVCoordinates(baseFrame).getPosition();
125 final T elevation = position.getDelta();
126
127 if (elevation.getReal() > 0.0) {
128 // Delay
129 return pathDelay(elevation, frequency, parameters);
130 }
131
132 return elevation.getField().getZero();
133 }
134
135 /**
136 * Calculates the ionospheric path delay for the signal path from a ground
137 * station to a satellite.
138 * <p>
139 * The path delay is computed for any elevation angle.
140 * </p>
141 * @param <T> type of the elements
142 * @param elevation elevation of the satellite in radians
143 * @param frequency frequency of the signal in Hz
144 * @param parameters ionospheric model parameters
145 * @return the path delay due to the ionosphere in m
146 */
147 public <T extends CalculusFieldElement<T>> T pathDelay(final T elevation, final double frequency, final T[] parameters) {
148 // Square of the frequency
149 final double freq2 = frequency * frequency;
150 // Mapping factor
151 final T fz = model.mappingFactor(elevation);
152 // "Slant" Total Electron Content
153 final T stec = parameters[0].multiply(fz);
154 // Delay computation
155 final double alpha = FACTOR / freq2;
156 return stec.multiply(alpha);
157 }
158
159 @Override
160 public List<ParameterDriver> getParametersDrivers() {
161 return Collections.singletonList(vtec);
162 }
163
164 }