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 public <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> getTargetPV(final FieldPVCoordinatesProvider<T> pvProv,
105 final FieldAbsoluteDate<T> date, final Frame frame) {
106
107
108 final TimeStampedFieldPVCoordinates<T> scInBodyFrame = pvProv.getPVCoordinates(date, getBodyFrame());
109
110
111 final T u = scInBodyFrame.getPosition().getX().divide(ellipsoid.getA());
112 final T v = scInBodyFrame.getPosition().getY().divide(ellipsoid.getB());
113 final T w = scInBodyFrame.getPosition().getZ().divide(ellipsoid.getC());
114 final T d2 = u.pow(2).add(v.pow(2)).add(w.pow(2));
115 final T d = d2.sqrt();
116 final T ratio = d.reciprocal();
117 final FieldVector3D<T> projectedP = new FieldVector3D<>(ratio, scInBodyFrame.getPosition());
118
119
120 final T uDot = scInBodyFrame.getVelocity().getX().divide(ellipsoid.getA());
121 final T vDot = scInBodyFrame.getVelocity().getY().divide(ellipsoid.getB());
122 final T wDot = scInBodyFrame.getVelocity().getZ().divide(ellipsoid.getC());
123
124 final T dDot = (u.multiply(uDot).add(v.multiply(vDot)).add(w.multiply(wDot))).divide(d);
125 final T ratioDot = dDot.multiply(-1).divide(d2);
126 final FieldVector3D<T> projectedV = new FieldVector3D<>(ratio, scInBodyFrame.getVelocity(),
127 ratioDot, scInBodyFrame.getPosition());
128
129
130 final T uDotDot = scInBodyFrame.getAcceleration().getX().divide(ellipsoid.getA());
131 final T vDotDot = scInBodyFrame.getAcceleration().getY().divide(ellipsoid.getB());
132 final T wDotDot = scInBodyFrame.getAcceleration().getZ().divide(ellipsoid.getC());
133 final T dDotDot = u.multiply(uDotDot).add(v.multiply(vDotDot)).add(w.multiply( wDotDot)
134 .add(uDot.pow(2).add(vDot.pow(2)).add(wDot.pow(2)).subtract(dDot.pow(2))))
135 .divide(d);
136 final T ratioDotDot = (dDot.pow(2).multiply(2).subtract(d.multiply(dDotDot))).divide(d.multiply(d2));
137 final FieldVector3D<T> projectedA = new FieldVector3D<>(ratio, scInBodyFrame.getAcceleration(),
138 ratioDot.multiply(2), scInBodyFrame.getVelocity(),
139 ratioDotDot, scInBodyFrame.getPosition());
140 final TimeStampedFieldPVCoordinates<T> projected =
141 new TimeStampedFieldPVCoordinates<>(date, projectedP, projectedV, projectedA);
142 return getBodyFrame().getTransformTo(frame, date.toAbsoluteDate()).transformPVCoordinates(projected);
143
144 }
145
146 }