1   /* Copyright 2022-2026 Romain Serra
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.signal;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.optim.ConvergenceChecker;
22  import org.hipparchus.optim.FieldScalarConvergenceCheckerProvider;
23  import org.hipparchus.util.FastMath;
24  import org.orekit.utils.FieldPVCoordinatesProvider;
25  import org.orekit.utils.PVCoordinatesProvider;
26  
27  /**
28   * Full model for signal travel time in vacuum (adjustable receiver/emitter with fixed emission/reception),
29   * compatible with Field.
30   * @since 14.0
31   * @author Romain Serra
32   */
33  public class SignalTravelTimeModel {
34  
35      /** Convergence checker for standard values. */
36      private final ConvergenceChecker<Double> convergenceChecker;
37  
38      /** Convergence checker provider for Field values. */
39      private final FieldScalarConvergenceCheckerProvider fieldConvergenceCheckerProvider;
40  
41      /**
42       * Constructor.
43       * @param convergenceChecker convergence settings for standard values
44       * @param fieldConvergenceCheckerProvider convergence settings for Field values
45       */
46      public SignalTravelTimeModel(final ConvergenceChecker<Double> convergenceChecker,
47                                   final FieldScalarConvergenceCheckerProvider fieldConvergenceCheckerProvider) {
48          this.convergenceChecker = convergenceChecker;
49          this.fieldConvergenceCheckerProvider = fieldConvergenceCheckerProvider;
50      }
51  
52      /**
53       * Constructor.
54       * @param convergenceChecker convergence settings for standard values
55       */
56      public SignalTravelTimeModel(final ConvergenceChecker<Double> convergenceChecker) {
57          this(convergenceChecker, new FieldScalarConvergenceCheckerProvider() {
58              @Override
59              public <T extends CalculusFieldElement<T>> ConvergenceChecker<T> getChecker(final Field<T> field) {
60                  return (iteration, previous, current) -> iteration != 0 && (iteration > AbstractSignalTravelTime.DEFAULT_MAX_ITER ||
61                          (previous.subtract(current)).norm() <= 2 * FastMath.ulp(current).getReal());
62              }
63          });
64      }
65  
66      /**
67       * Constructor.
68       */
69      public SignalTravelTimeModel() {
70          this(AbstractSignalTravelTime.getDefaultConvergenceChecker());
71      }
72  
73      /**
74       * Getter for the convergence checker.
75       * @return checker
76       */
77      public ConvergenceChecker<Double> getConvergenceChecker() {
78          return convergenceChecker;
79      }
80  
81      /**
82       * Getter for the Field convergence checker provider.
83       * @return provider
84       */
85      public FieldScalarConvergenceCheckerProvider getFieldConvergenceCheckerProvider() {
86          return fieldConvergenceCheckerProvider;
87      }
88  
89      /**
90       * Method returning a model assuming an iteration of the fixed point algorithm has already been performed.
91       * @return warmed-up signal model
92       */
93      public SignalTravelTimeModel getWarmedUpModel() {
94          return new SignalTravelTimeModel((iteration, previous, current) -> convergenceChecker.converged(iteration + 1, previous, current),
95                  new FieldScalarConvergenceCheckerProvider() {
96                      @Override
97                      public <T extends CalculusFieldElement<T>> ConvergenceChecker<T> getChecker(final Field<T> field) {
98                          return (iteration, previous, current) -> fieldConvergenceCheckerProvider.getChecker(field)
99                                  .converged(iteration + 1, previous, current);
100                     }
101                 });
102     }
103 
104     /**
105      * Method constructing a delay computer with input emitter.
106      * @param emitter signal emitter
107      * @return (positive) time delay
108      */
109     public AdjustableEmitterSignalTimer getAdjustableEmitterComputer(final PVCoordinatesProvider emitter) {
110         return new AdjustableEmitterSignalTimer(emitter, convergenceChecker);
111     }
112 
113     /**
114      * Method constructing a delay computer with input receiver.
115      * @param receiver signal emitter
116      * @return (positive) time delay
117      */
118     public AdjustableReceiverSignalTimer getAdjustableReceiverComputer(final PVCoordinatesProvider receiver) {
119         return new AdjustableReceiverSignalTimer(receiver, convergenceChecker);
120     }
121 
122     /**
123      * Method constructing a delay computer with input emitter.
124      * @param <T> field type
125      * @param field field
126      * @param emitter signal emitter
127      * @return (positive) time delay
128      */
129     public <T extends CalculusFieldElement<T>> FieldAdjustableEmitterSignalTimer<T> getFieldAdjustableEmitterComputer(final Field<T> field,
130                                                                                                                       final FieldPVCoordinatesProvider<T> emitter) {
131         return new FieldAdjustableEmitterSignalTimer<>(emitter, fieldConvergenceCheckerProvider.getChecker(field));
132     }
133 
134     /**
135      * Method constructing a delay computer with input receiver.
136      * @param <T> field type
137      * @param field field
138      * @param receiver signal receiver
139      * @return (positive) time delay
140      */
141     public <T extends CalculusFieldElement<T>> FieldAdjustableReceiverSignalTimer<T> getFieldAdjustableReceiverComputer(final Field<T> field,
142                                                                                                                         final FieldPVCoordinatesProvider<T> receiver) {
143         return new FieldAdjustableReceiverSignalTimer<>(receiver, fieldConvergenceCheckerProvider.getChecker(field));
144     }
145 }