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.orekit.attitudes.FrameAlignedProvider;
23  import org.orekit.estimation.measurements.EstimatedMeasurement;
24  import org.orekit.estimation.measurements.EstimatedMeasurementBase;
25  import org.orekit.estimation.measurements.EstimationModifier;
26  import org.orekit.estimation.measurements.GroundStation;
27  import org.orekit.estimation.measurements.TDOA;
28  import org.orekit.frames.TopocentricFrame;
29  import org.orekit.models.earth.ionosphere.IonosphericModel;
30  import org.orekit.propagation.FieldSpacecraftState;
31  import org.orekit.propagation.SpacecraftState;
32  import org.orekit.utils.Constants;
33  import org.orekit.utils.ParameterDriver;
34  
35  /** Class modifying theoretical TDOA measurements with ionospheric delay.
36   * <p>
37   * The effect of ionospheric correction on the TDOA is a time delay computed
38   * directly from the difference in ionospheric delays for each downlink.
39   * </p><p>
40   * The ionospheric delay depends on the frequency of the signal.
41   * </p>
42   * @author Pascal Parraud
43   * @since 11.2
44   */
45  public class TDOAIonosphericDelayModifier implements EstimationModifier<TDOA> {
46  
47      /** Ionospheric delay model. */
48      private final IonosphericModel ionoModel;
49  
50      /** Frequency [Hz]. */
51      private final double frequency;
52  
53      /** Constructor.
54       *
55       * @param model ionospheric model appropriate for the current TDOA measurement method
56       * @param freq  frequency of the signal in Hz
57       */
58      public TDOAIonosphericDelayModifier(final IonosphericModel model,
59                                          final double freq) {
60          ionoModel = model;
61          frequency = freq;
62      }
63  
64      /** Compute the measurement error due to ionosphere on a single downlink.
65       * @param station station
66       * @param state spacecraft state
67       * @return the measurement error due to ionosphere (s)
68       */
69      private double timeErrorIonosphericModel(final GroundStation station,
70                                               final SpacecraftState state) {
71          // base frame associated with the station
72          final TopocentricFrame baseFrame = station.getBaseFrame();
73          // delay in meters
74          final double delay = ionoModel.pathDelay(state, baseFrame, frequency, ionoModel.getParameters(state.getDate()));
75          // return delay in seconds
76          return delay / Constants.SPEED_OF_LIGHT;
77      }
78  
79      /** Compute the measurement error due to ionosphere on a single downlink.
80       * @param <T> type of the elements
81       * @param station station
82       * @param state spacecraft state
83       * @param parameters ionospheric model parameters
84       * @return the measurement error due to ionosphere (s)
85       */
86      private <T extends CalculusFieldElement<T>> T timeErrorIonosphericModel(final GroundStation station,
87                                                                              final FieldSpacecraftState<T> state,
88                                                                              final T[] parameters) {
89          // Base frame associated with the station
90          final TopocentricFrame baseFrame = station.getBaseFrame();
91          // Delay in meters
92          final T delay = ionoModel.pathDelay(state, baseFrame, frequency, parameters);
93          // return delay in seconds
94          return delay.divide(Constants.SPEED_OF_LIGHT);
95      }
96  
97      /** {@inheritDoc} */
98      @Override
99      public List<ParameterDriver> getParametersDrivers() {
100         return ionoModel.getParametersDrivers();
101     }
102 
103     @Override
104     public void modifyWithoutDerivatives(final EstimatedMeasurementBase<TDOA> estimated) {
105 
106         final TDOA measurement              = estimated.getObservedMeasurement();
107         final GroundStation   primeStation  = measurement.getPrimeStation();
108         final GroundStation   secondStation = measurement.getSecondStation();
109 
110         TDOAModifierUtil.modifyWithoutDerivatives(estimated,  primeStation, secondStation,
111                                                   this::timeErrorIonosphericModel,
112                                                   this);
113 
114     }
115 
116     @Override
117     public void modify(final EstimatedMeasurement<TDOA> estimated) {
118 
119         final TDOA measurement              = estimated.getObservedMeasurement();
120         final GroundStation   primeStation  = measurement.getPrimeStation();
121         final GroundStation   secondStation = measurement.getSecondStation();
122         final SpacecraftState state         = estimated.getStates()[0];
123 
124         TDOAModifierUtil.modify(estimated, ionoModel,
125                                 new ModifierGradientConverter(state, 6, new FrameAlignedProvider(state.getFrame())),
126                                 primeStation, secondStation,
127                                 this::timeErrorIonosphericModel,
128                                 this::timeErrorIonosphericModel,
129                                 this);
130 
131     }
132 
133 }