1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements.model;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.util.FastMath;
23 import org.hipparchus.util.MathArrays;
24 import org.orekit.annotation.DefaultDataContext;
25 import org.orekit.bodies.BodyShape;
26 import org.orekit.bodies.FieldGeodeticPoint;
27 import org.orekit.bodies.GeodeticPoint;
28 import org.orekit.errors.OrekitException;
29 import org.orekit.errors.OrekitMessages;
30 import org.orekit.frames.FieldStaticTransform;
31 import org.orekit.frames.Frame;
32 import org.orekit.frames.FramesFactory;
33 import org.orekit.frames.StaticTransform;
34 import org.orekit.signal.FieldSignalReceptionCondition;
35 import org.orekit.signal.SignalReceptionCondition;
36 import org.orekit.signal.SignalTravelTimeModel;
37 import org.orekit.time.AbsoluteDate;
38 import org.orekit.time.FieldAbsoluteDate;
39 import org.orekit.utils.FieldPVCoordinatesProvider;
40 import org.orekit.utils.PVCoordinatesProvider;
41
42
43
44
45
46
47
48 public class TopocentricAzElModel extends AbstractAngularMeasurementModel {
49
50
51 private final BodyShape bodyShape;
52
53
54 private final Frame inertialFrame;
55
56
57
58
59
60
61 @DefaultDataContext
62 public TopocentricAzElModel(final BodyShape bodyShape,
63 final SignalTravelTimeModel signalTravelTimeModel) {
64 this(FramesFactory.getGCRF(), bodyShape, signalTravelTimeModel);
65 }
66
67
68
69
70
71
72
73 public TopocentricAzElModel(final Frame inertialFrame, final BodyShape bodyShape,
74 final SignalTravelTimeModel signalTravelTimeModel) {
75 super(signalTravelTimeModel);
76 if (!inertialFrame.isPseudoInertial()) {
77 throw new OrekitException(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME, inertialFrame.getName());
78 }
79 this.inertialFrame = inertialFrame;
80 this.bodyShape = bodyShape;
81 }
82
83
84
85
86
87
88
89
90 public double[] value(final GeodeticPoint receiver, final AbsoluteDate receptionDate,
91 final PVCoordinatesProvider emitter) {
92 return value(receiver, receptionDate, emitter, receptionDate);
93 }
94
95
96
97
98
99
100
101
102
103 public double[] value(final GeodeticPoint receiver, final AbsoluteDate receptionDate,
104 final PVCoordinatesProvider emitter, final AbsoluteDate approxEmissionDate) {
105
106 final Frame bodyFixedFrame = bodyShape.getBodyFrame();
107 final Vector3D bodyFixedReceiverPosition = bodyShape.transform(receiver);
108 final StaticTransform toInertialFrameAtReception = bodyFixedFrame.getStaticTransformTo(inertialFrame, receptionDate);
109 final Vector3D receiverPosition = toInertialFrameAtReception.transformPosition(bodyFixedReceiverPosition);
110 final SignalReceptionCondition receptionCondition = new SignalReceptionCondition(receptionDate, receiverPosition,
111 inertialFrame);
112 final Vector3D apparentLineOfSight = getEmitterToReceiverVector(receptionCondition, emitter, approxEmissionDate)
113 .normalize();
114
115
116 final Vector3D east = toInertialFrameAtReception.transformVector(receiver.getEast());
117 final Vector3D north = toInertialFrameAtReception.transformVector(receiver.getNorth());
118 final Vector3D zenith = toInertialFrameAtReception.transformVector(receiver.getZenith());
119 final double azimuth = FastMath.atan2(apparentLineOfSight.dotProduct(east), apparentLineOfSight.dotProduct(north));
120 final double elevation = FastMath.asin(apparentLineOfSight.dotProduct(zenith) / apparentLineOfSight.getNorm2());
121 return new double[] { azimuth, elevation };
122 }
123
124
125
126
127
128
129
130
131
132 public <T extends CalculusFieldElement<T>> T[] value(final FieldGeodeticPoint<T> receiver,
133 final FieldAbsoluteDate<T> receptionDate,
134 final FieldPVCoordinatesProvider<T> emitter) {
135 return value(receiver, receptionDate, emitter, receptionDate);
136 }
137
138
139
140
141
142
143
144
145
146
147 public <T extends CalculusFieldElement<T>> T[] value(final FieldGeodeticPoint<T> receiver,
148 final FieldAbsoluteDate<T> receptionDate,
149 final FieldPVCoordinatesProvider<T> emitter,
150 final FieldAbsoluteDate<T> approxEmissionDate) {
151
152 final Frame bodyFixedFrame = bodyShape.getBodyFrame();
153 final FieldVector3D<T> bodyFixedReceiverPosition = bodyShape.transform(receiver);
154 final FieldStaticTransform<T> toInertialFrameAtReception = bodyFixedFrame.getStaticTransformTo(inertialFrame,
155 receptionDate);
156 final FieldVector3D<T> receiverPosition = toInertialFrameAtReception.transformPosition(bodyFixedReceiverPosition);
157 final FieldSignalReceptionCondition<T> receptionCondition = new FieldSignalReceptionCondition<>(receptionDate,
158 receiverPosition, inertialFrame);
159 final FieldVector3D<T> apparentLineOfSight = getEmitterToReceiverVector(receptionCondition, emitter, approxEmissionDate).normalize();
160
161
162 final FieldVector3D<T> east = toInertialFrameAtReception.transformVector(receiver.getEast());
163 final FieldVector3D<T> north = toInertialFrameAtReception.transformVector(receiver.getNorth());
164 final FieldVector3D<T> zenith = toInertialFrameAtReception.transformVector(receiver.getZenith());
165 final T azimuth = FastMath.atan2(apparentLineOfSight.dotProduct(east),
166 apparentLineOfSight.dotProduct(north));
167 final T elevation = FastMath.asin(apparentLineOfSight.dotProduct(zenith)
168 .divide(apparentLineOfSight.getNorm2()));
169 final T[] output = MathArrays.buildArray(receiverPosition.getX().getField(), 2);
170 output[0] = azimuth;
171 output[1] = elevation;
172 return output;
173 }
174 }