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.PVCoordinates;
31 import org.orekit.utils.ParameterDriver;
32
33 import java.util.Arrays;
34
35
36
37
38
39 public class FDOAMeasurementCreator extends MeasurementCreator {
40
41 private final Context context;
42 private final GroundStation secondary;
43 private final GroundStation primary;
44 private final ObservableSatellite satellite;
45 private final double centreFrequency;
46
47 public FDOAMeasurementCreator(final Context context, final double centreFrequency) {
48 this.context = context;
49 this.secondary = context.TDOAstations.getKey();
50 this.primary = context.TDOAstations.getValue();
51 this.satellite = new ObservableSatellite(0);
52 this.centreFrequency = centreFrequency;
53 }
54
55 public ObservableSatellite getSatellite() {
56 return satellite;
57 }
58
59 public void init(SpacecraftState s0, AbsoluteDate t, double step) {
60 for (final GroundStation station : Arrays.asList(context.TDOAstations.getKey(),
61 context.TDOAstations.getValue())) {
62 for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
63 station.getEastOffsetDriver(),
64 station.getNorthOffsetDriver(),
65 station.getZenithOffsetDriver(),
66 station.getPrimeMeridianOffsetDriver(),
67 station.getPrimeMeridianDriftDriver(),
68 station.getPolarOffsetXDriver(),
69 station.getPolarDriftXDriver(),
70 station.getPolarOffsetYDriver(),
71 station.getPolarDriftYDriver())) {
72 if (driver.getReferenceDate() == null) {
73 driver.setReferenceDate(s0.getDate());
74 }
75 }
76 }
77 }
78
79 public void handleStep(final SpacecraftState currentState) {
80
81 final AbsoluteDate date = currentState.getDate();
82 final Frame inertial = currentState.getFrame();
83 final Vector3D position = currentState.getPosition();
84 final Vector3D velocity = currentState.getPVCoordinates().getVelocity();
85
86
87 if ((secondary.getBaseFrame().getTrackingCoordinates(position, inertial, date).getElevation() > FastMath.toRadians(30.0)) &&
88 (primary.getBaseFrame().getTrackingCoordinates(position, inertial, date).getElevation() > FastMath.toRadians(30.0))) {
89
90
91 final UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 5);
92
93 final double primaryDelay = solver.solve(1000, new UnivariateFunction() {
94 public double value(final double x) {
95 final Transform t = primary.getOffsetToInertial(inertial, date.shiftedBy(x), false);
96 final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
97 return d - x * Constants.SPEED_OF_LIGHT;
98 }
99 }, -1.0, 1.0);
100
101 final AbsoluteDate primaryReceptionDate = currentState.getDate().shiftedBy(primaryDelay);
102 final PVCoordinates primaryPV = primary.getOffsetToInertial(inertial, primaryReceptionDate, false)
103 .transformPVCoordinates(PVCoordinates.ZERO);
104
105
106 final Vector3D primaryLOS = (position.subtract(primaryPV.getPosition())).normalize();
107
108
109 final Vector3D deltaVp = velocity.subtract(primaryPV.getVelocity());
110
111 final double secondaryDelay = solver.solve(1000, new UnivariateFunction() {
112 public double value(final double x) {
113 final Transform t = secondary.getOffsetToInertial(inertial, date.shiftedBy(x), false);
114 final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
115 return d - x * Constants.SPEED_OF_LIGHT;
116 }
117 }, -1.0, 1.0);
118
119 final AbsoluteDate secondaryReceptionDate = currentState.getDate().shiftedBy(secondaryDelay);
120 final PVCoordinates secondaryPV = secondary.getOffsetToInertial(inertial, secondaryReceptionDate, false)
121 .transformPVCoordinates(PVCoordinates.ZERO);
122
123
124 final Vector3D secondaryLOS = (position.subtract(secondaryPV.getPosition())).normalize();
125
126
127 final Vector3D deltaVs = velocity.subtract(secondaryPV.getVelocity());
128
129
130 final double rrDifference = deltaVp.dotProduct(primaryLOS) - deltaVs.dotProduct(secondaryLOS);
131 final double fdoa = rrDifference * centreFrequency / Constants.SPEED_OF_LIGHT;
132
133 addMeasurement(new FDOA(secondary, primary, centreFrequency, primaryReceptionDate,
134 fdoa, 1.0, 10, satellite));
135
136 }
137
138 }
139 }