1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.orbits;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.util.FastMath;
22 import org.hipparchus.util.FieldSinCos;
23 import org.orekit.errors.OrekitIllegalArgumentException;
24 import org.orekit.errors.OrekitMessages;
25 import org.orekit.utils.FieldPVCoordinates;
26
27
28
29
30
31
32
33
34
35 public class FieldEquinoctialParametersConverter<T extends CalculusFieldElement<T>> {
36
37
38 private final T mu;
39
40
41
42
43
44 public FieldEquinoctialParametersConverter(final T mu) {
45 this.mu = mu;
46 }
47
48
49
50
51
52
53
54 public FieldEquinoctialParameters<T> toParameters(final FieldPVCoordinates<T> cartesian,
55 final PositionAngleType positionAngleType) {
56
57 final FieldVector3D<T> pvP = cartesian.getPosition();
58 final T r = pvP.getNorm2();
59 final T v2 = cartesian.getVelocity().getNorm2Sq();
60 final T rV2OnMu = r.multiply(v2).divide(mu);
61 final T a = r.divide(rV2OnMu.negate().add(2));
62
63 if (a.getReal() < 0.) {
64 throw new OrekitIllegalArgumentException(OrekitMessages.HYPERBOLIC_ORBIT_NOT_HANDLED_AS,
65 getClass().getName());
66 }
67
68
69 final FieldVector3D<T> w = cartesian.getMomentum().normalize();
70 final T one = a.getField().getOne();
71 final T d = one.divide(one.add(w.getZ()));
72 final T hx = d.negate().multiply(w.getY());
73 final T hy = d.multiply(w.getX());
74
75
76 final T cLv = (pvP.getX().subtract(d.multiply(pvP.getZ()).multiply(w.getX()))).divide(r);
77 final T sLv = (pvP.getY().subtract(d.multiply(pvP.getZ()).multiply(w.getY()))).divide(r);
78 final T trueLongitude = sLv.atan2(cLv);
79
80
81 final T eSE = FieldVector3D.dotProduct(pvP, cartesian.getVelocity()).divide(a.multiply(mu).sqrt());
82 final T eCE = rV2OnMu.subtract(1);
83 final T e2 = eCE.square().add(eSE.square());
84 final T f = eCE.subtract(e2);
85 final T g = e2.negate().add(1).sqrt().multiply(eSE);
86 final T ex = a.multiply(f.multiply(cLv).add( g.multiply(sLv))).divide(r);
87 final T ey = a.multiply(f.multiply(sLv).subtract(g.multiply(cLv))).divide(r);
88
89 final FieldEquinoctialParameters<T> equinoctialParameters = new FieldEquinoctialParameters<>(a, ex, ey, hx, hy,
90 trueLongitude, PositionAngleType.TRUE);
91 return positionAngleType == PositionAngleType.TRUE ? equinoctialParameters :
92 equinoctialParameters.withPositionAngleType(positionAngleType);
93 }
94
95
96
97
98
99
100 public FieldPVCoordinates<T> toCartesian(final FieldEquinoctialParameters<T> elements) {
101
102 final T a = elements.a();
103 final T ex = elements.ex();
104 final T ey = elements.ey();
105 final T hx = elements.hx();
106 final T hy = elements.hy();
107 final T lE = elements.positionAngleType() == PositionAngleType.ECCENTRIC ? elements.longitudeArgument() :
108 elements.withPositionAngleType(PositionAngleType.ECCENTRIC).longitudeArgument();
109
110
111 final T hx2 = hx.square();
112 final T hy2 = hy.square();
113 final T one = a.getField().getOne();
114 final T factH = one.divide(hx2.add(1.0).add(hy2));
115
116
117 final T ux = hx2.add(1.0).subtract(hy2).multiply(factH);
118 final T uy = hx.multiply(hy).multiply(factH).multiply(2);
119 final T uz = hy.multiply(-2).multiply(factH);
120
121 final T vx = uy;
122 final T vy = (hy2.subtract(hx2).add(1)).multiply(factH);
123 final T vz = hx.multiply(factH).multiply(2);
124
125
126 final T ex2 = ex.square();
127 final T exey = ex.multiply(ey);
128 final T ey2 = ey.square();
129 final T e2 = ex2.add(ey2);
130 final T eta = one.subtract(e2).sqrt().add(1);
131 final T beta = one.divide(eta);
132
133
134 final FieldSinCos<T> scLe = FastMath.sinCos(lE);
135 final T cLe = scLe.cos();
136 final T sLe = scLe.sin();
137 final T exCeyS = ex.multiply(cLe).add(ey.multiply(sLe));
138
139
140 final T x = a.multiply(one.subtract(beta.multiply(ey2)).multiply(cLe).add(beta.multiply(exey).multiply(sLe)).subtract(ex));
141 final T y = a.multiply(one.subtract(beta.multiply(ex2)).multiply(sLe).add(beta .multiply(exey).multiply(cLe)).subtract(ey));
142
143 final T factor = mu.divide(a).sqrt().divide(one.subtract(exCeyS));
144 final T xdot = factor.multiply(sLe.negate().add(beta.multiply(ey).multiply(exCeyS)));
145 final T ydot = factor.multiply(cLe.subtract(beta.multiply(ex).multiply(exCeyS)));
146
147 final FieldVector3D<T> position =
148 new FieldVector3D<>(x.multiply(ux).add(y.multiply(vx)),
149 x.multiply(uy).add(y.multiply(vy)),
150 x.multiply(uz).add(y.multiply(vz)));
151 final FieldVector3D<T> velocity =
152 new FieldVector3D<>(xdot.multiply(ux).add(ydot.multiply(vx)), xdot.multiply(uy).add(ydot.multiply(vy)), xdot.multiply(uz).add(ydot.multiply(vz)));
153
154 return new FieldPVCoordinates<>(position, velocity);
155 }
156 }