1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements;
18
19 import org.hipparchus.analysis.UnivariateFunction;
20 import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
21 import org.hipparchus.analysis.solvers.UnivariateSolver;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.util.FastMath;
24 import org.orekit.estimation.Context;
25 import org.orekit.frames.Frame;
26 import org.orekit.frames.Transform;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.time.AbsoluteDate;
29 import org.orekit.utils.Constants;
30 import org.orekit.utils.ParameterDriver;
31
32 import java.util.Arrays;
33
34 public class BistaticRangeMeasurementCreator extends MeasurementCreator {
35
36 private final Context context;
37 private final GroundStation emitter;
38 private final GroundStation receiver;
39 private final ObservableSatellite satellite;
40
41
42 public BistaticRangeMeasurementCreator(final Context context) {
43 this.context = context;
44 this.emitter = context.BRRstations.getKey();
45 this.receiver = context.BRRstations.getValue();
46 this.satellite = new ObservableSatellite(0);
47 }
48
49 public ObservableSatellite getSatellite() {
50 return satellite;
51 }
52
53 public void init(SpacecraftState s0, AbsoluteDate t, double step) {
54 for (final GroundStation station : Arrays.asList(context.BRRstations.getKey(),
55 context.BRRstations.getValue())) {
56 for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
57 station.getEastOffsetDriver(),
58 station.getNorthOffsetDriver(),
59 station.getZenithOffsetDriver(),
60 station.getPrimeMeridianOffsetDriver(),
61 station.getPrimeMeridianDriftDriver(),
62 station.getPolarOffsetXDriver(),
63 station.getPolarDriftXDriver(),
64 station.getPolarOffsetYDriver(),
65 station.getPolarDriftYDriver())) {
66 if (driver.getReferenceDate() == null) {
67 driver.setReferenceDate(s0.getDate());
68 }
69 }
70 }
71 }
72
73 public void handleStep(final SpacecraftState currentState) {
74 final AbsoluteDate date = currentState.getDate();
75 final Frame inertial = currentState.getFrame();
76 final Vector3D position = currentState.getPosition();
77
78
79 if ((emitter.getBaseFrame().getTrackingCoordinates(position, inertial, date).getElevation() > FastMath.toRadians(30.0)) &&
80 (receiver.getBaseFrame().getTrackingCoordinates(position, inertial, date).getElevation() > FastMath.toRadians(30.0))) {
81 final double clockOffset = receiver.getClockOffsetDriver().getValue();
82 final UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 5);
83
84 final double downLinkDelay = solver.solve(1000, new UnivariateFunction() {
85 public double value(final double x) {
86 final Transform t = receiver.getOffsetToInertial(inertial, date.shiftedBy(clockOffset + x), false);
87 final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
88 return d - x * Constants.SPEED_OF_LIGHT;
89 }
90 }, -1.0, 1.0);
91 final AbsoluteDate receptionDate = currentState.getDate().shiftedBy(downLinkDelay);
92 final Vector3D stationAtReception =
93 receiver.getOffsetToInertial(inertial, receptionDate.shiftedBy(clockOffset), false).transformPosition(Vector3D.ZERO);
94 final double downLinkDistance = Vector3D.distance(position, stationAtReception);
95
96 final double upLinkDelay = solver.solve(1000, new UnivariateFunction() {
97 public double value(final double x) {
98 final Transform t = emitter.getOffsetToInertial(inertial, date.shiftedBy(clockOffset - x), false);
99 final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
100 return d - x * Constants.SPEED_OF_LIGHT;
101 }
102 }, -1.0, 1.0);
103 final AbsoluteDate emissionDate = currentState.getDate().shiftedBy(-upLinkDelay);
104 final Vector3D stationAtEmission =
105 emitter.getOffsetToInertial(inertial, emissionDate.shiftedBy(clockOffset), false).transformPosition(Vector3D.ZERO);
106 final double upLinkDistance = Vector3D.distance(position, stationAtEmission);
107 addMeasurement(new BistaticRange(emitter, receiver, receptionDate.shiftedBy(clockOffset),
108 downLinkDistance + upLinkDistance, 1.0, 10, satellite));
109 }
110
111 }
112
113 }