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.utils.ExtendedPositionProvider;
32 import org.orekit.time.FieldAbsoluteDate;
33 import org.orekit.utils.FieldPVCoordinates;
34 import org.orekit.utils.FieldPVCoordinatesProvider;
35 import org.orekit.utils.PVCoordinates;
36 import org.orekit.utils.PVCoordinatesProvider;
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
67 public class CelestialBodyPointed implements AttitudeProvider {
68
69
70 private final Frame celestialFrame;
71
72
73 private final ExtendedPositionProvider pointedBody;
74
75
76 private final Vector3D phasingCel;
77
78
79 private final Vector3D pointingSat;
80
81
82 private final Vector3D phasingSat;
83
84
85
86
87
88
89
90
91 public CelestialBodyPointed(final Frame celestialFrame,
92 final ExtendedPositionProvider pointedBody,
93 final Vector3D phasingCel,
94 final Vector3D pointingSat,
95 final Vector3D phasingSat) {
96 this.celestialFrame = celestialFrame;
97 this.pointedBody = pointedBody;
98 this.phasingCel = phasingCel;
99 this.pointingSat = pointingSat;
100 this.phasingSat = phasingSat;
101 }
102
103
104 @Override
105 public Attitude getAttitude(final PVCoordinatesProvider pvProv,
106 final AbsoluteDate date, final Frame frame) {
107
108 final PVCoordinates satPV = pvProv.getPVCoordinates(date, celestialFrame);
109
110
111 final PVCoordinates bodyPV = pointedBody.getPVCoordinates(date, celestialFrame);
112 final PVCoordinates pointing = new PVCoordinates(satPV, bodyPV);
113 final Vector3D pointingP = pointing.getPosition();
114 final double r2 = Vector3D.dotProduct(pointingP, pointingP);
115
116
117 final Vector3D rotAxisCel = new Vector3D(1 / r2, Vector3D.crossProduct(pointingP, pointing.getVelocity()));
118
119
120
121
122 final Vector3D v1 = Vector3D.crossProduct(rotAxisCel, phasingCel);
123 final Vector3D v2 = Vector3D.crossProduct(pointingP, phasingCel);
124 final double compensation = -Vector3D.dotProduct(v1, v2) / v2.getNormSq();
125 final Vector3D phasedRotAxisCel = new Vector3D(1.0, rotAxisCel, compensation, pointingP);
126
127
128 final Rotation celToSatRotation =
129 new Rotation(pointingP, phasingCel, pointingSat, phasingSat);
130
131
132 Transform transform = new Transform(date, celToSatRotation, celToSatRotation.applyTo(phasedRotAxisCel));
133 if (frame != celestialFrame) {
134
135 transform = new Transform(date, frame.getTransformTo(celestialFrame, date), transform);
136 }
137
138
139 return new Attitude(date, frame, transform.getRotation(), transform.getRotationRate(), transform.getRotationAcceleration());
140
141 }
142
143
144 @Override
145 public Rotation getAttitudeRotation(final PVCoordinatesProvider pvProv,
146 final AbsoluteDate date,
147 final Frame frame) {
148 final Vector3D satPosition = pvProv.getPosition(date, celestialFrame);
149
150
151 final Vector3D bodyPosition = pointedBody.getPosition(date, celestialFrame);
152 final Vector3D pointingP = bodyPosition.subtract(satPosition);
153
154
155 final Rotation celToSatRotation = new Rotation(pointingP, phasingCel, pointingSat, phasingSat);
156 StaticTransform staticTransform = StaticTransform.of(date, celToSatRotation);
157
158 if (frame != celestialFrame) {
159
160 staticTransform = StaticTransform.compose(date, frame.getStaticTransformTo(celestialFrame, date), staticTransform);
161 }
162 return staticTransform.getRotation();
163 }
164
165
166 @Override
167 public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
168 final FieldAbsoluteDate<T> date,
169 final Frame frame) {
170
171 final Field<T> field = date.getField();
172 final FieldPVCoordinates<T> satPV = pvProv.getPVCoordinates(date, celestialFrame);
173
174
175 final FieldPVCoordinates<T> bodyPV = pointedBody.getPVCoordinates(date, celestialFrame);
176 final FieldPVCoordinates<T> pointing = new FieldPVCoordinates<>(satPV, bodyPV);
177 final FieldVector3D<T> pointingP = pointing.getPosition();
178 final T r2 = FieldVector3D.dotProduct(pointingP, pointingP);
179
180
181 final FieldVector3D<T> rotAxisCel =
182 new FieldVector3D<>(r2.reciprocal(), FieldVector3D.crossProduct(pointingP, pointing.getVelocity()));
183
184
185
186
187 final FieldVector3D<T> v1 = FieldVector3D.crossProduct(rotAxisCel, phasingCel);
188 final FieldVector3D<T> v2 = FieldVector3D.crossProduct(pointingP, phasingCel);
189 final T compensation = FieldVector3D.dotProduct(v1, v2).negate().divide(v2.getNormSq());
190 final FieldVector3D<T> phasedRotAxisCel = new FieldVector3D<>(field.getOne(), rotAxisCel, compensation, pointingP);
191
192
193 final FieldRotation<T> celToSatRotation =
194 new FieldRotation<>(pointingP, new FieldVector3D<>(field, phasingCel),
195 new FieldVector3D<>(field, pointingSat), new FieldVector3D<>(field, phasingSat));
196
197
198 FieldTransform<T> transform = new FieldTransform<>(date, celToSatRotation, celToSatRotation.applyTo(phasedRotAxisCel));
199 if (frame != celestialFrame) {
200
201 transform = new FieldTransform<>(date, frame.getTransformTo(celestialFrame, date), transform);
202 }
203
204
205 return new FieldAttitude<>(date, frame,
206 transform.getRotation(), transform.getRotationRate(), transform.getRotationAcceleration());
207
208 }
209
210
211 @Override
212 public <T extends CalculusFieldElement<T>> FieldRotation<T> getAttitudeRotation(final FieldPVCoordinatesProvider<T> pvProv,
213 final FieldAbsoluteDate<T> date,
214 final Frame frame) {
215 final Field<T> field = date.getField();
216 final FieldVector3D<T> satPosition = pvProv.getPosition(date, celestialFrame);
217
218
219 final FieldVector3D<T> bodyPosition = pointedBody.getPosition(date, celestialFrame);
220 final FieldVector3D<T> pointingP = bodyPosition.subtract(satPosition);
221
222
223 final FieldRotation<T> celToSatRotation =
224 new FieldRotation<>(pointingP, new FieldVector3D<>(field, phasingCel),
225 new FieldVector3D<>(field, pointingSat), new FieldVector3D<>(field, phasingSat));
226
227
228 FieldStaticTransform<T> staticTransform = FieldStaticTransform.of(date, celToSatRotation);
229 if (frame != celestialFrame) {
230
231 staticTransform = FieldStaticTransform.compose(date, frame.getStaticTransformTo(celestialFrame, date), staticTransform);
232 }
233 return staticTransform.getRotation();
234 }
235 }