1 /* Copyright 2002-2026 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 org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.orekit.bodies.GeodeticPoint;
23 import org.orekit.bodies.OneAxisEllipsoid;
24 import org.orekit.frames.FieldStaticTransform;
25 import org.orekit.frames.Frame;
26 import org.orekit.frames.StaticTransform;
27 import org.orekit.frames.TopocentricFrame;
28 import org.orekit.propagation.FieldSpacecraftState;
29 import org.orekit.propagation.SpacecraftState;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.time.FieldAbsoluteDate;
32 import org.orekit.utils.PVCoordinatesProvider;
33 import org.orekit.utils.ParameterDriversProvider;
34
35 /** Defines a ionospheric model, used to calculate the path delay imposed to
36 * electro-magnetic signals between an orbital satellite and a ground station.
37 * <p>
38 * Since 10.0, this interface can be used for models that aspire to estimate
39 * ionospheric parameters.
40 * </p>
41 *
42 * @author Joris Olympio
43 * @author Bryan Cazabonne
44 * @author Luc Maisonobe
45 * @author Brianna Aubin
46 * @since 13.0.3
47 */
48 public interface IonosphericModel extends ParameterDriversProvider {
49
50 /** Lambda header for calculating the path delay.
51 */
52 @FunctionalInterface
53 interface DelayCalculator {
54 /** Apply delay calculation.
55 * @param pos position in Earth frame
56 * @return path delay
57 */
58 Double apply(Vector3D pos);
59 }
60
61 /** Lambda header for calculating the path delay.
62 * @param <T> type of the field element
63 */
64 @FunctionalInterface
65 interface FieldDelayCalculator<T extends CalculusFieldElement<T>> {
66 /** Apply delay calculation.
67 * @param pos position in Earth frame
68 * @return path delay
69 */
70 T apply(FieldVector3D<T> pos);
71 }
72
73 /** Get the earth body shape for earth-frame calculations.
74 * @return earth body shape
75 * @since 14.0
76 */
77 OneAxisEllipsoid getEarth();
78
79 /**
80 * Calculates the ionospheric path delay for the signal path from an observation
81 * object to the satellite being measured.
82 * <p>
83 * This method is intended to be used for orbit determination issues.
84 * In that respect, if the elevation is below 0° the path delay will be equal to zero.
85 * </p><p>
86 * For individual use of the ionospheric model (i.e. not for orbit determination), another
87 * method signature can be implemented to compute the path delay for any elevation angle.
88 * </p>
89 * @param state spacecraft state
90 * @param coordsProvider coordinates provider for the observing object
91 * @param frequency frequency of the signal in Hz
92 * @param parameters ionospheric model parameters at state date
93 * @return the path delay due to the ionosphere in m
94 */
95 default double pathDelay(final SpacecraftState state,
96 final PVCoordinatesProvider coordsProvider,
97 final double frequency,
98 final double[] parameters) {
99
100 // Solve for the lowest altitude point between p1 and p2
101 final OneAxisEllipsoid earth = getEarth();
102 final Frame bodyFrame = earth.getFrame();
103 final AbsoluteDate receptionDate = state.getDate();
104 final Vector3D p1 = state.getPVCoordinates(bodyFrame).getPosition();
105 final Vector3D p2 = coordsProvider.getPosition(receptionDate, bodyFrame);
106 final GeodeticPoint lowAltPoint = earth.lowestAltitudeIntermediate(p1, p2);
107
108 // Solve for the positions of p1 and p2 in the topocentric frame of
109 // the lowest altitude point
110 final TopocentricFrame baseFrame = new TopocentricFrame(earth, lowAltPoint, null);
111 final StaticTransform base2Inert = baseFrame.getStaticTransformTo(bodyFrame, receptionDate);
112 final Vector3D localP1 = base2Inert.getInverse().transformPosition(p1);
113 final Vector3D localP2 = base2Inert.getInverse().transformPosition(p2);
114
115 return pathDelay(localP1, localP2, baseFrame, receptionDate, frequency, parameters);
116 }
117
118 /**
119 * Calculates the ionospheric path delay for the signal path from a ground
120 * station to an observing object (ground station or satellite).
121 * <p>
122 * This method is intended to be used for orbit determination issues.
123 * In that respect, if the elevation is below 0° the path delay will be equal to zero.
124 * </p><p>
125 * For individual use of the ionospheric model (i.e. not for orbit determination), another
126 * method signature can be implemented to compute the path delay for any elevation angle.
127 * </p>
128 * @param localP1 position of path start point in baseFrame
129 * @param localP2 position of path end point in baseFrame
130 * @param baseFrame topocentric frame of point with lowest altitude between p1 and p2
131 * @param receptionDate date at signal reception
132 * @param frequency frequency of the signal in Hz
133 * @param parameters ionospheric model parameters at state date
134 * @return the path delay due to the ionosphere in m
135 */
136 double pathDelay(Vector3D localP1, Vector3D localP2,
137 TopocentricFrame baseFrame, AbsoluteDate receptionDate,
138 double frequency, double[] parameters);
139
140 /**
141 * Calculates the ionospheric path delay for the signal path from an observation
142 * object to the satellite being measured.
143 * <p>
144 * This method is intended to be used for orbit determination issues.
145 * In that respect, if the elevation is below 0° the path delay will be equal to zero.
146 * </p><p>
147 * For individual use of the ionospheric model (i.e. not for orbit determination), another
148 * method signature can be implemented to compute the path delay for any elevation angle.
149 * </p>
150 * @param <T> type of the elements
151 * @param state spacecraft state
152 * @param coordsProvider coordinates provider for the observing object
153 * @param frequency frequency of the signal in Hz
154 * @param parameters ionospheric model parameters at state date
155 * @return the path delay due to the ionosphere in m
156 */
157 default <T extends CalculusFieldElement<T>> T pathDelay(final FieldSpacecraftState<T> state,
158 final PVCoordinatesProvider coordsProvider,
159 final double frequency,
160 final T[] parameters) {
161
162 // Solve for the lowest altitude point between p1 and p2
163 final OneAxisEllipsoid earth = getEarth();
164 final Frame bodyFrame = earth.getFrame();
165 final FieldAbsoluteDate<T> receptionDate = state.getDate();
166 final FieldVector3D<T> p1 = state.getPVCoordinates(bodyFrame).getPosition();
167 final Vector3D p2 = coordsProvider.getPosition(receptionDate.toAbsoluteDate(), bodyFrame);
168 final GeodeticPoint lowAltPoint = earth.lowestAltitudeIntermediate(p1.toVector3D(), p2);
169
170 final TopocentricFrame baseFrame = new TopocentricFrame(earth, lowAltPoint, null);
171 final FieldStaticTransform<T> base2Inert = baseFrame.getStaticTransformTo(bodyFrame, receptionDate);
172 final FieldVector3D<T> localP1 = base2Inert.getInverse().transformPosition(p1);
173 final FieldVector3D<T> localP2 = base2Inert.getInverse().transformPosition(p2);
174
175 return pathDelay(localP1, localP2, baseFrame, receptionDate, frequency, parameters);
176 }
177
178 /**
179 * Calculates the ionospheric path delay for the signal path from a ground
180 * station to an observing object (ground station or satellite).
181 * <p>
182 * This method is intended to be used for orbit determination issues.
183 * In that respect, if the elevation is below 0° the path delay will be equal to zero.
184 * </p><p>
185 * For individual use of the ionospheric model (i.e. not for orbit determination), another
186 * method signature can be implemented to compute the path delay for any elevation angle.
187 * </p>
188 * @param <T> type of the elements
189 * @param localP1 position of path start point in baseFrame
190 * @param localP2 position of path end point in baseFrame
191 * @param baseFrame topocentric frame of point with lowest altitude between p1 and p2
192 * @param receptionDate date at signal reception
193 * @param frequency frequency of the signal in Hz
194 * @param parameters ionospheric model parameters at state date
195 * @return the path delay due to the ionosphere in m
196 */
197 <T extends CalculusFieldElement<T>> T pathDelay(FieldVector3D<T> localP1, FieldVector3D<T> localP2,
198 TopocentricFrame baseFrame, FieldAbsoluteDate<T> receptionDate,
199 double frequency, T[] parameters);
200
201 }