1   /* Copyright 2002-2025 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.CalculusFieldElement;
20  import org.orekit.attitudes.FrameAlignedProvider;
21  import org.orekit.estimation.measurements.EstimatedMeasurement;
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.estimation.measurements.RangeRate;
26  import org.orekit.models.earth.ionosphere.IonosphericModel;
27  import org.orekit.propagation.FieldSpacecraftState;
28  import org.orekit.propagation.SpacecraftState;
29  
30  /** Class modifying theoretical range-rate measurement with ionospheric delay.
31   * <p>
32   * The effect of ionospheric correction on the range-rate is directly computed
33   * through the computation of the ionospheric delay difference with respect to
34   * time.
35   * </p>
36   * <p>
37   * The ionospheric delay depends on the frequency of the signal (GNSS, VLBI, ...).
38   * For optical measurements (e.g. SLR), the ray is not affected by ionosphere charged particles.
39   * </p>
40   * <p>
41   * Since 10.0, state derivatives and ionospheric parameters derivates are computed
42   * using automatic differentiation.
43   * </p>
44   * @author Joris Olympio
45   * @since 8.0
46   */
47  public class RangeRateIonosphericDelayModifier extends BaseRangeRateIonosphericDelayModifier implements EstimationModifier<RangeRate> {
48  
49      /** Coefficient for measurment configuration (one-way, two-way). */
50      private final double fTwoWay;
51  
52      /** Constructor.
53       *
54       * @param model Ionospheric delay model appropriate for the current range-rate measurement method.
55       * @param freq frequency of the signal in Hz
56       * @param twoWay Flag indicating whether the measurement is two-way.
57       */
58      public RangeRateIonosphericDelayModifier(final IonosphericModel model,
59                                               final double freq, final boolean twoWay) {
60          super(model, freq);
61  
62          if (twoWay) {
63              fTwoWay = 2.;
64          } else {
65              fTwoWay = 1.;
66          }
67      }
68  
69      /** {@inheritDoc} */
70      @Override
71      protected double rangeRateErrorIonosphericModel(final GroundStation station, final SpacecraftState state) {
72          return fTwoWay * super.rangeRateErrorIonosphericModel(station, state);
73      }
74  
75      /** {@inheritDoc} */
76      @Override
77      protected <T extends CalculusFieldElement<T>> T rangeRateErrorIonosphericModel(final GroundStation station,
78                                                                                     final FieldSpacecraftState<T> state,
79                                                                                     final T[] parameters) {
80          return super.rangeRateErrorIonosphericModel(station, state, parameters).multiply(fTwoWay);
81      }
82  
83      /** {@inheritDoc} */
84      @Override
85      public void modifyWithoutDerivatives(final EstimatedMeasurementBase<RangeRate> estimated) {
86  
87          final RangeRate       measurement = estimated.getObservedMeasurement();
88          final GroundStation   station     = measurement.getStation();
89  
90          RangeModifierUtil.modifyWithoutDerivatives(estimated,  station,
91                                                     this::rangeRateErrorIonosphericModel,
92                                                     this);
93  
94      }
95  
96      /** {@inheritDoc} */
97      @Override
98      public void modify(final EstimatedMeasurement<RangeRate> estimated) {
99  
100         final RangeRate       measurement = estimated.getObservedMeasurement();
101         final GroundStation   station     = measurement.getStation();
102         final SpacecraftState state       = estimated.getStates()[0];
103 
104         RangeModifierUtil.modify(estimated, getIonoModel(),
105                                  new ModifierGradientConverter(state, 6, new FrameAlignedProvider(state.getFrame())),
106                                  station,
107                                  this::rangeRateErrorIonosphericModel,
108                                  this::rangeRateErrorIonosphericModel,
109                                  this);
110 
111 
112     }
113 
114 }