1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.attitudes;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
22 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23 import org.hipparchus.geometry.euclidean.threed.Rotation;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.orekit.frames.FieldStaticTransform;
26 import org.orekit.frames.FieldTransform;
27 import org.orekit.frames.Frame;
28 import org.orekit.frames.StaticTransform;
29 import org.orekit.frames.Transform;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.time.FieldAbsoluteDate;
32 import org.orekit.utils.FieldPVCoordinates;
33 import org.orekit.utils.FieldPVCoordinatesProvider;
34 import org.orekit.utils.PVCoordinates;
35 import org.orekit.utils.PVCoordinatesProvider;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class CelestialBodyPointed implements AttitudeProvider {
67
68
69 private final Frame celestialFrame;
70
71
72 private final PVCoordinatesProvider pointedBody;
73
74
75 private final Vector3D phasingCel;
76
77
78 private final Vector3D pointingSat;
79
80
81 private final Vector3D phasingSat;
82
83
84
85
86
87
88
89
90 public CelestialBodyPointed(final Frame celestialFrame,
91 final PVCoordinatesProvider pointedBody,
92 final Vector3D phasingCel,
93 final Vector3D pointingSat,
94 final Vector3D phasingSat) {
95 this.celestialFrame = celestialFrame;
96 this.pointedBody = pointedBody;
97 this.phasingCel = phasingCel;
98 this.pointingSat = pointingSat;
99 this.phasingSat = phasingSat;
100 }
101
102
103 @Override
104 public Attitude getAttitude(final PVCoordinatesProvider pvProv,
105 final AbsoluteDate date, final Frame frame) {
106
107 final PVCoordinates satPV = pvProv.getPVCoordinates(date, celestialFrame);
108
109
110 final PVCoordinates bodyPV = pointedBody.getPVCoordinates(date, celestialFrame);
111 final PVCoordinates pointing = new PVCoordinates(satPV, bodyPV);
112 final Vector3D pointingP = pointing.getPosition();
113 final double r2 = Vector3D.dotProduct(pointingP, pointingP);
114
115
116 final Vector3D rotAxisCel = new Vector3D(1 / r2, Vector3D.crossProduct(pointingP, pointing.getVelocity()));
117
118
119
120
121 final Vector3D v1 = Vector3D.crossProduct(rotAxisCel, phasingCel);
122 final Vector3D v2 = Vector3D.crossProduct(pointingP, phasingCel);
123 final double compensation = -Vector3D.dotProduct(v1, v2) / v2.getNormSq();
124 final Vector3D phasedRotAxisCel = new Vector3D(1.0, rotAxisCel, compensation, pointingP);
125
126
127 final Rotation celToSatRotation =
128 new Rotation(pointingP, phasingCel, pointingSat, phasingSat);
129
130
131 Transform transform = new Transform(date, celToSatRotation, celToSatRotation.applyTo(phasedRotAxisCel));
132 if (frame != celestialFrame) {
133
134 transform = new Transform(date, frame.getTransformTo(celestialFrame, date), transform);
135 }
136
137
138 return new Attitude(date, frame, transform.getRotation(), transform.getRotationRate(), transform.getRotationAcceleration());
139
140 }
141
142
143 @Override
144 public Rotation getAttitudeRotation(final PVCoordinatesProvider pvProv,
145 final AbsoluteDate date,
146 final Frame frame) {
147 final Vector3D satPosition = pvProv.getPosition(date, celestialFrame);
148
149
150 final Vector3D bodyPosition = pointedBody.getPosition(date, celestialFrame);
151 final Vector3D pointingP = bodyPosition.subtract(satPosition);
152
153
154 final Rotation celToSatRotation = new Rotation(pointingP, phasingCel, pointingSat, phasingSat);
155 StaticTransform staticTransform = StaticTransform.of(date, celToSatRotation);
156
157 if (frame != celestialFrame) {
158
159 staticTransform = StaticTransform.compose(date, frame.getStaticTransformTo(celestialFrame, date), staticTransform);
160 }
161 return staticTransform.getRotation();
162 }
163
164
165 @Override
166 public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
167 final FieldAbsoluteDate<T> date,
168 final Frame frame) {
169
170 final Field<T> field = date.getField();
171 final FieldPVCoordinates<T> satPV = pvProv.getPVCoordinates(date, celestialFrame);
172
173
174 final FieldPVCoordinates<T> bodyPV = new FieldPVCoordinates<>(field,
175 pointedBody.getPVCoordinates(date.toAbsoluteDate(),
176 celestialFrame));
177 final FieldPVCoordinates<T> pointing = new FieldPVCoordinates<>(satPV, bodyPV);
178 final FieldVector3D<T> pointingP = pointing.getPosition();
179 final T r2 = FieldVector3D.dotProduct(pointingP, pointingP);
180
181
182 final FieldVector3D<T> rotAxisCel =
183 new FieldVector3D<>(r2.reciprocal(), FieldVector3D.crossProduct(pointingP, pointing.getVelocity()));
184
185
186
187
188 final FieldVector3D<T> v1 = FieldVector3D.crossProduct(rotAxisCel, phasingCel);
189 final FieldVector3D<T> v2 = FieldVector3D.crossProduct(pointingP, phasingCel);
190 final T compensation = FieldVector3D.dotProduct(v1, v2).negate().divide(v2.getNormSq());
191 final FieldVector3D<T> phasedRotAxisCel = new FieldVector3D<>(field.getOne(), rotAxisCel, compensation, pointingP);
192
193
194 final FieldRotation<T> celToSatRotation =
195 new FieldRotation<>(pointingP, new FieldVector3D<>(field, phasingCel),
196 new FieldVector3D<>(field, pointingSat), new FieldVector3D<>(field, phasingSat));
197
198
199 FieldTransform<T> transform = new FieldTransform<>(date, celToSatRotation, celToSatRotation.applyTo(phasedRotAxisCel));
200 if (frame != celestialFrame) {
201
202 transform = new FieldTransform<>(date, frame.getTransformTo(celestialFrame, date), transform);
203 }
204
205
206 return new FieldAttitude<>(date, frame,
207 transform.getRotation(), transform.getRotationRate(), transform.getRotationAcceleration());
208
209 }
210
211
212 @Override
213 public <T extends CalculusFieldElement<T>> FieldRotation<T> getAttitudeRotation(final FieldPVCoordinatesProvider<T> pvProv,
214 final FieldAbsoluteDate<T> date,
215 final Frame frame) {
216 final Field<T> field = date.getField();
217 final FieldVector3D<T> satPosition = pvProv.getPosition(date, celestialFrame);
218
219
220 final FieldVector3D<T> bodyPosition = new FieldVector3D<>(field,
221 pointedBody.getPosition(date.toAbsoluteDate(), celestialFrame));
222 final FieldVector3D<T> pointingP = bodyPosition.subtract(satPosition);
223
224
225 final FieldRotation<T> celToSatRotation =
226 new FieldRotation<>(pointingP, new FieldVector3D<>(field, phasingCel),
227 new FieldVector3D<>(field, pointingSat), new FieldVector3D<>(field, phasingSat));
228
229
230 FieldStaticTransform<T> staticTransform = FieldStaticTransform.of(date, celToSatRotation);
231 if (frame != celestialFrame) {
232
233 staticTransform = FieldStaticTransform.compose(date, frame.getStaticTransformTo(celestialFrame, date), staticTransform);
234 }
235 return staticTransform.getRotation();
236 }
237 }