1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative1;
21 import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
22 import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
23 import org.hipparchus.analysis.differentiation.UnivariateDerivative1Field;
24 import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
25 import org.hipparchus.analysis.differentiation.UnivariateDerivative2Field;
26 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
27 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
28 import org.hipparchus.geometry.euclidean.threed.Rotation;
29 import org.hipparchus.geometry.euclidean.threed.Vector3D;
30 import org.hipparchus.util.Precision;
31 import org.orekit.frames.FieldKinematicTransform;
32 import org.orekit.frames.FieldStaticTransform;
33 import org.orekit.frames.FieldTransform;
34 import org.orekit.frames.Frame;
35 import org.orekit.frames.KinematicTransform;
36 import org.orekit.frames.StaticTransform;
37 import org.orekit.frames.Transform;
38 import org.orekit.frames.TransformProvider;
39 import org.orekit.time.AbsoluteDate;
40 import org.orekit.time.FieldAbsoluteDate;
41 import org.orekit.utils.AngularCoordinates;
42 import org.orekit.utils.ExtendedPositionProvider;
43 import org.orekit.utils.FieldAngularCoordinates;
44 import org.orekit.utils.FieldPVCoordinates;
45 import org.orekit.utils.PVCoordinates;
46
47
48
49
50
51
52
53 class JPLInertialTransformProvider implements TransformProvider {
54
55
56 private final Frame definingFrame;
57
58 private final ExtendedPositionProvider pvProvider;
59
60 private final IAUPole iauPole;
61
62
63
64
65
66
67
68 JPLInertialTransformProvider(final Frame definingFrame, final ExtendedPositionProvider pvProvider,
69 final IAUPole iauPole) {
70 this.definingFrame = definingFrame;
71 this.pvProvider = pvProvider;
72 this.iauPole = iauPole;
73 }
74
75
76
77
78
79 Frame getDefiningFrame() {
80 return definingFrame;
81 }
82
83
84 @Override
85 public Transform getTransform(final AbsoluteDate date) {
86
87 final PVCoordinates pv = pvProvider.getPVCoordinates(date, definingFrame).negate();
88
89
90 final AngularCoordinates angularCoordinates = getAngularCoordinates(date, true);
91
92
93 return new Transform(date, pv, angularCoordinates);
94
95 }
96
97
98 @Override
99 public KinematicTransform getKinematicTransform(final AbsoluteDate date) {
100
101 final PVCoordinates pv = pvProvider.getPVCoordinates(date, definingFrame).negate();
102
103
104 final AngularCoordinates angularCoordinates = getAngularCoordinates(date, false);
105
106
107 return KinematicTransform.of(date, pv, angularCoordinates.getRotation(), angularCoordinates.getRotationRate());
108
109 }
110
111
112
113
114
115
116
117 private AngularCoordinates getAngularCoordinates(final AbsoluteDate date, final boolean order2) {
118 if (order2) {
119 final UnivariateDerivative2Field field = UnivariateDerivative2Field.getInstance();
120 final UnivariateDerivative2 dt = new UnivariateDerivative2(0, 1, 0);
121 final FieldAbsoluteDate<UnivariateDerivative2> ud2Date =
122 new FieldAbsoluteDate<>(field, date).shiftedBy(dt);
123 return new AngularCoordinates(getRotation(ud2Date));
124 } else {
125 final UnivariateDerivative1Field field = UnivariateDerivative1Field.getInstance();
126 final UnivariateDerivative1 dt = new UnivariateDerivative1(0, 1);
127 final FieldAbsoluteDate<UnivariateDerivative1> ud1Date =
128 new FieldAbsoluteDate<>(field, date).shiftedBy(dt);
129 return new AngularCoordinates(getRotation(ud1Date));
130 }
131 }
132
133
134 @Override
135 public StaticTransform getStaticTransform(final AbsoluteDate date) {
136
137 final Vector3D position = pvProvider.getPVCoordinates(date, definingFrame).getPosition().negate();
138
139
140
141
142
143
144
145
146
147 final Vector3D pole = iauPole.getPole(date);
148 Vector3D qNode = iauPole.getNode(date);
149 if (qNode.getNormSq() < Precision.SAFE_MIN) {
150 qNode = Vector3D.crossProduct(Vector3D.PLUS_K, pole);
151 }
152 final Rotation rotation = new Rotation(pole, qNode, Vector3D.PLUS_K, Vector3D.PLUS_I);
153 return StaticTransform.of(date, position, rotation);
154 }
155
156
157 @Override
158 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
159
160 final FieldPVCoordinates<T> pv = pvProvider.getPVCoordinates(date, definingFrame).negate();
161
162
163 final FieldRotation<T> rotation = getRotation(date);
164
165
166 final FieldAbsoluteDate<FieldUnivariateDerivative2<T>> fud2Date = date.toFUD2Field();
167 final FieldAngularCoordinates<T> derivatives = new FieldAngularCoordinates<>(getRotation(fud2Date));
168
169
170 return new FieldTransform<>(date, new FieldTransform<>(date, pv),
171 new FieldTransform<>(date, new FieldAngularCoordinates<>(rotation, derivatives.getRotationRate(),
172 derivatives.getRotationAcceleration())));
173
174 }
175
176
177 @Override
178 public <T extends CalculusFieldElement<T>> FieldKinematicTransform<T> getKinematicTransform(final FieldAbsoluteDate<T> date) {
179
180 final FieldPVCoordinates<T> pv = pvProvider.getPVCoordinates(date, definingFrame).negate();
181
182
183 final FieldRotation<T> rotation = getRotation(date);
184
185
186 final FieldAbsoluteDate<FieldUnivariateDerivative1<T>> fud1Date = date.toFUD1Field();
187 final FieldAngularCoordinates<T> derivatives = new FieldAngularCoordinates<>(getRotation(fud1Date));
188
189
190 return FieldKinematicTransform.of(date, pv, rotation, derivatives.getRotationRate());
191
192 }
193
194
195 @Override
196 public <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {
197 final FieldVector3D<T> position = pvProvider.getPVCoordinates(date, definingFrame).getPosition().negate();
198 return FieldStaticTransform.of(date, position, getRotation(date));
199 }
200
201
202
203
204
205
206 private <T extends CalculusFieldElement<T>> FieldRotation<T> getRotation(final FieldAbsoluteDate<T> date) {
207
208
209
210
211
212
213
214
215
216 final FieldVector3D<T> pole = iauPole.getPole(date);
217 FieldVector3D<T> qNode = iauPole.getNode(date);
218 if (qNode.getNormSq().getReal() < Precision.SAFE_MIN) {
219 qNode = FieldVector3D.crossProduct(Vector3D.PLUS_K, pole);
220 }
221 return new FieldRotation<>(pole, qNode, FieldVector3D.getPlusK(date.getField()),
222 FieldVector3D.getPlusI(date.getField()));
223 }
224
225 }