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.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.optim.ConvergenceChecker;
21 import org.orekit.frames.Frame;
22 import org.orekit.time.AbsoluteDate;
23 import org.orekit.utils.PVCoordinatesProvider;
24
25 /**
26 * Class for computing signal time of travel with an adjustable emitter and a fixed receiver's position and date.
27 * The delay is calculated via a fixed-point algorithm with customizable settings (even enabling instantaneous transmission).
28 * Note that a couple of iterations are usually enough for Earth orbits.
29 * @since 14.0
30 * @author Romain Serra
31 */
32 public class AdjustableEmitterSignalTimer extends AbstractSignalTravelTime {
33
34 /** Position/velocity provider of emitter. */
35 private final PVCoordinatesProvider adjustableEmitterPVProvider;
36
37 /**
38 * Constructor with default iteration settings.
39 * @param adjustableEmitterPVProvider adjustable emitter
40 */
41 public AdjustableEmitterSignalTimer(final PVCoordinatesProvider adjustableEmitterPVProvider) {
42 this(adjustableEmitterPVProvider, getDefaultConvergenceChecker());
43 }
44
45 /**
46 * Constructor.
47 * @param adjustableEmitterPVProvider adjustable emitter
48 * @param checker convergence checker for fixed-point algorithm
49 */
50 public AdjustableEmitterSignalTimer(final PVCoordinatesProvider adjustableEmitterPVProvider,
51 final ConvergenceChecker<Double> checker) {
52 super(checker);
53 this.adjustableEmitterPVProvider = adjustableEmitterPVProvider;
54 }
55
56 /** Compute the signal emission condition on a link leg (typically downlink or uplink).
57 * @param approxEmissionDate approximate emission date
58 * @param receptionCondition signal reception condition
59 * @return emission condition
60 */
61 public SignalEmissionCondition computeEmissionCondition(final SignalReceptionCondition receptionCondition,
62 final AbsoluteDate approxEmissionDate) {
63 final double delay = computeDelay(receptionCondition, approxEmissionDate);
64 final AbsoluteDate emissionDate = receptionCondition.receptionDate().shiftedBy(-delay);
65 final Frame frame = receptionCondition.referenceFrame();
66 return new SignalEmissionCondition(emissionDate, adjustableEmitterPVProvider.getPosition(emissionDate, frame), frame);
67 }
68
69 /** Compute propagation delay on a link leg (typically downlink or uplink) without custom guess.
70 * @param receptionCondition signal reception condition
71 * @return <em>positive</em> delay between signal emission and signal reception dates
72 */
73 public double computeDelay(final SignalReceptionCondition receptionCondition) {
74 final AbsoluteDate signalArrivalDate = receptionCondition.receptionDate();
75 final Vector3D emitterPosition = adjustableEmitterPVProvider.getPosition(receptionCondition.receptionDate(),
76 receptionCondition.referenceFrame());
77 final Vector3D receiverPosition = receptionCondition.receiverPosition();
78 final double distance = receiverPosition.subtract(emitterPosition).getNorm();
79 final AbsoluteDate approxEmissionDate = signalArrivalDate.shiftedBy(-distance * C_RECIPROCAL);
80 return computeDelay(receptionCondition, approxEmissionDate);
81 }
82
83 /** Compute propagation delay on a link leg (typically downlink or uplink).
84 * @param approxEmissionDate approximate emission date
85 * @param receptionCondition signal reception condition
86 * @return <em>positive</em> delay between signal emission and signal reception dates
87 */
88 public double computeDelay(final SignalReceptionCondition receptionCondition, final AbsoluteDate approxEmissionDate) {
89
90 // initialize emission date search loop assuming the state is already correct
91 final double offset = receptionCondition.receptionDate().durationFrom(approxEmissionDate);
92
93 return compute(adjustableEmitterPVProvider, offset, receptionCondition.receiverPosition(), approxEmissionDate,
94 receptionCondition.referenceFrame());
95 }
96
97 @Override
98 protected double computeShift(final double offset, final double delay) {
99 return offset - delay;
100 }
101 }