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.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.bodies.Ellipsoid;
25 import org.orekit.frames.Frame;
26 import org.orekit.time.AbsoluteDate;
27 import org.orekit.time.FieldAbsoluteDate;
28 import org.orekit.utils.FieldPVCoordinatesProvider;
29 import org.orekit.utils.PVCoordinatesProvider;
30 import org.orekit.utils.TimeStampedFieldPVCoordinates;
31 import org.orekit.utils.TimeStampedPVCoordinates;
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class BodyCenterPointing extends GroundPointing {
46
47
48 private final Ellipsoid ellipsoid;
49
50
51
52
53
54
55 public BodyCenterPointing(final Frame inertialFrame, final Ellipsoid shape) {
56 super(inertialFrame, shape.getFrame());
57 this.ellipsoid = shape;
58 }
59
60
61 @Override
62 public TimeStampedPVCoordinates getTargetPV(final PVCoordinatesProvider pvProv,
63 final AbsoluteDate date, final Frame frame) {
64
65
66 final TimeStampedPVCoordinates scInBodyFrame = pvProv.getPVCoordinates(date, getBodyFrame());
67
68
69 final double u = scInBodyFrame.getPosition().getX() / ellipsoid.getA();
70 final double v = scInBodyFrame.getPosition().getY() / ellipsoid.getB();
71 final double w = scInBodyFrame.getPosition().getZ() / ellipsoid.getC();
72 final double d2 = u * u + v * v + w * w;
73 final double d = FastMath.sqrt(d2);
74 final double ratio = 1.0 / d;
75 final Vector3D projectedP = new Vector3D(ratio, scInBodyFrame.getPosition());
76
77
78 final double uDot = scInBodyFrame.getVelocity().getX() / ellipsoid.getA();
79 final double vDot = scInBodyFrame.getVelocity().getY() / ellipsoid.getB();
80 final double wDot = scInBodyFrame.getVelocity().getZ() / ellipsoid.getC();
81 final double dDot = MathArrays.linearCombination(u, uDot, v, vDot, w, wDot) / d;
82 final double ratioDot = -dDot / d2;
83 final Vector3D projectedV = new Vector3D(ratio, scInBodyFrame.getVelocity(),
84 ratioDot, scInBodyFrame.getPosition());
85
86
87 final double uDotDot = scInBodyFrame.getAcceleration().getX() / ellipsoid.getA();
88 final double vDotDot = scInBodyFrame.getAcceleration().getY() / ellipsoid.getB();
89 final double wDotDot = scInBodyFrame.getAcceleration().getZ() / ellipsoid.getC();
90 final double dDotDot = (MathArrays.linearCombination(u, uDotDot, v, vDotDot, w, wDotDot) +
91 uDot * uDot + vDot * vDot + wDot * wDot - dDot * dDot) / d;
92 final double ratioDotDot = (2 * dDot * dDot - d * dDotDot) / (d * d2);
93 final Vector3D projectedA = new Vector3D(ratio, scInBodyFrame.getAcceleration(),
94 2 * ratioDot, scInBodyFrame.getVelocity(),
95 ratioDotDot, scInBodyFrame.getPosition());
96
97 final TimeStampedPVCoordinates projected =
98 new TimeStampedPVCoordinates(date, projectedP, projectedV, projectedA);
99 return getBodyFrame().getTransformTo(frame, date).transformPVCoordinates(projected);
100
101 }
102
103
104 @Override
105 protected Vector3D getTargetPosition(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) {
106
107 final Vector3D scPositionInBodyFrame = pvProv.getPosition(date, getBodyFrame());
108
109
110 final double u = scPositionInBodyFrame.getX() / ellipsoid.getA();
111 final double v = scPositionInBodyFrame.getY() / ellipsoid.getB();
112 final double w = scPositionInBodyFrame.getZ() / ellipsoid.getC();
113 final double d2 = u * u + v * v + w * w;
114 final double d = FastMath.sqrt(d2);
115 final double ratio = 1.0 / d;
116 final Vector3D projectedP = new Vector3D(ratio, scPositionInBodyFrame);
117
118 return getBodyFrame().getStaticTransformTo(frame, date).transformPosition(projectedP);
119 }
120
121
122 public <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> getTargetPV(final FieldPVCoordinatesProvider<T> pvProv,
123 final FieldAbsoluteDate<T> date,
124 final Frame frame) {
125
126
127 final TimeStampedFieldPVCoordinates<T> scInBodyFrame = pvProv.getPVCoordinates(date, getBodyFrame());
128
129
130 final T u = scInBodyFrame.getPosition().getX().divide(ellipsoid.getA());
131 final T v = scInBodyFrame.getPosition().getY().divide(ellipsoid.getB());
132 final T w = scInBodyFrame.getPosition().getZ().divide(ellipsoid.getC());
133 final T d2 = u.pow(2).add(v.pow(2)).add(w.pow(2));
134 final T d = d2.sqrt();
135 final T ratio = d.reciprocal();
136 final FieldVector3D<T> projectedP = new FieldVector3D<>(ratio, scInBodyFrame.getPosition());
137
138
139 final T uDot = scInBodyFrame.getVelocity().getX().divide(ellipsoid.getA());
140 final T vDot = scInBodyFrame.getVelocity().getY().divide(ellipsoid.getB());
141 final T wDot = scInBodyFrame.getVelocity().getZ().divide(ellipsoid.getC());
142
143 final T dDot = (u.multiply(uDot).add(v.multiply(vDot)).add(w.multiply(wDot))).divide(d);
144 final T ratioDot = dDot.multiply(-1).divide(d2);
145 final FieldVector3D<T> projectedV = new FieldVector3D<>(ratio, scInBodyFrame.getVelocity(),
146 ratioDot, scInBodyFrame.getPosition());
147
148
149 final T uDotDot = scInBodyFrame.getAcceleration().getX().divide(ellipsoid.getA());
150 final T vDotDot = scInBodyFrame.getAcceleration().getY().divide(ellipsoid.getB());
151 final T wDotDot = scInBodyFrame.getAcceleration().getZ().divide(ellipsoid.getC());
152 final T dDotDot = u.multiply(uDotDot).add(v.multiply(vDotDot)).add(w.multiply( wDotDot)
153 .add(uDot.pow(2).add(vDot.pow(2)).add(wDot.pow(2)).subtract(dDot.pow(2))))
154 .divide(d);
155 final T ratioDotDot = (dDot.pow(2).multiply(2).subtract(d.multiply(dDotDot))).divide(d.multiply(d2));
156 final FieldVector3D<T> projectedA = new FieldVector3D<>(ratio, scInBodyFrame.getAcceleration(),
157 ratioDot.multiply(2), scInBodyFrame.getVelocity(),
158 ratioDotDot, scInBodyFrame.getPosition());
159 final TimeStampedFieldPVCoordinates<T> projected =
160 new TimeStampedFieldPVCoordinates<>(date, projectedP, projectedV, projectedA);
161 return getBodyFrame().getTransformTo(frame, date).transformPVCoordinates(projected);
162
163 }
164
165
166 @Override
167 protected <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetPosition(final FieldPVCoordinatesProvider<T> pvProv,
168 final FieldAbsoluteDate<T> date,
169 final Frame frame) {
170
171 final FieldVector3D<T> scPositionInBodyFrame = pvProv.getPosition(date, getBodyFrame());
172
173
174 final T u = scPositionInBodyFrame.getX().divide(ellipsoid.getA());
175 final T v = scPositionInBodyFrame.getY().divide(ellipsoid.getB());
176 final T w = scPositionInBodyFrame.getZ().divide(ellipsoid.getC());
177 final T d = new FieldVector3D<>(u, v, w).getNorm();
178 final FieldVector3D<T> projectedP = new FieldVector3D<>(d.reciprocal(), scPositionInBodyFrame);
179
180 return getBodyFrame().getStaticTransformTo(frame, date).transformPosition(projectedP);
181 }
182 }