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.analysis.differentiation.Gradient;
20 import org.hipparchus.analysis.differentiation.GradientField;
21 import org.hipparchus.complex.Complex;
22 import org.hipparchus.complex.ComplexField;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.hipparchus.util.FastMath;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.params.ParameterizedTest;
29 import org.junit.jupiter.params.provider.ValueSource;
30 import org.orekit.frames.FramesFactory;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.utils.DerivativeStateUtils;
33 import org.orekit.utils.FieldPVCoordinates;
34 import org.orekit.utils.PVCoordinates;
35
36 class KeplerianMotionCartesianUtilityTest {
37
38 private static final double TOLERANCE_DISTANCE = 1e-13;
39 private static final double TOLERANCE_SPEED = 1e-14;
40
41 @Test
42 void testPredictPositionVelocityElliptic() {
43
44 final double mu = 1.;
45 final Vector3D position = new Vector3D(10., 1., 0.);
46 final Vector3D velocity = new Vector3D(0., 0.1, 0.2);
47
48 for (double dt = -10.; dt <= 10.; dt += 0.1) {
49 final PVCoordinates actualPV = KeplerianMotionCartesianUtility.predictPositionVelocity(dt, position,
50 velocity, mu);
51 final CartesianOrbit orbit = new CartesianOrbit(new PVCoordinates(position, velocity), FramesFactory.getGCRF(),
52 AbsoluteDate.ARBITRARY_EPOCH, mu);
53 final EquinoctialOrbit equinoctialOrbit = new EquinoctialOrbit(orbit);
54 final PVCoordinates expectedPV = equinoctialOrbit.shiftedBy(dt).getPVCoordinates();
55 comparePV(expectedPV, actualPV);
56 }
57 }
58
59 @Test
60 void testPredictPositionVelocityHyperbolic() {
61
62 final double mu = 1.;
63 final Vector3D position = new Vector3D(10., 1., 0.);
64 final Vector3D velocity = new Vector3D(0., 0.1, 1.);
65
66 for (double dt = -10.; dt <= 10.; dt += 0.1) {
67 final PVCoordinates actualPV = KeplerianMotionCartesianUtility.predictPositionVelocity(dt, position,
68 velocity, mu);
69 final CartesianOrbit orbit = new CartesianOrbit(new PVCoordinates(position, velocity), FramesFactory.getGCRF(),
70 AbsoluteDate.ARBITRARY_EPOCH, mu);
71 final KeplerianOrbit keplerianOrbit = new KeplerianOrbit(orbit);
72 final PVCoordinates expectedPV = keplerianOrbit.shiftedBy(dt).getPVCoordinates();
73 comparePV(expectedPV, actualPV);
74 }
75 }
76
77 private void comparePV(final PVCoordinates pvCoordinates, final PVCoordinates otherPVCoordinates) {
78 comparePV(pvCoordinates, otherPVCoordinates, TOLERANCE_DISTANCE, TOLERANCE_SPEED);
79 }
80
81 private void comparePV(final PVCoordinates pvCoordinates, final PVCoordinates otherPVCoordinates,
82 final double toleranceDistance, final double toleranceSpeed) {
83 final double expectedValue = 0.;
84 final PVCoordinates relativePV = new PVCoordinates(pvCoordinates, otherPVCoordinates);
85 Assertions.assertEquals(expectedValue, relativePV.getPosition().getNorm(), toleranceDistance);
86 Assertions.assertEquals(expectedValue, relativePV.getVelocity().getNorm(), toleranceSpeed);
87 }
88
89 @ParameterizedTest
90 @ValueSource(doubles = {0., 1e-20, 1e-15, 1e-10, 1e-8, 1e-5, 1e-2, 1e-1})
91 void testPredictPositionVelocityCircularField(final double speedShift) {
92
93 final double mu = 1.5;
94 final Vector3D position = new Vector3D(4., 0., 0.);
95 final Vector3D velocity = new Vector3D(0., FastMath.sqrt(mu / position.getNorm()) + speedShift, 0.);
96 final GradientField field = GradientField.getField(6);
97 final Gradient fieldMu = new Gradient(mu, new double[6]);
98 final FieldOrbit<Gradient> fieldOrbit = DerivativeStateUtils.buildOrbitGradient(field,
99 new CartesianOrbit(new PVCoordinates(position, velocity), FramesFactory.getGCRF(), AbsoluteDate.ARBITRARY_EPOCH, mu));
100 final FieldVector3D<Gradient> fieldPosition = fieldOrbit.getPosition();
101 final FieldVector3D<Gradient> fieldVelocity = fieldOrbit.getVelocity();
102
103 for (double dt = -10.; dt <= 10.; dt += 0.1) {
104 final Gradient fieldDt = new Gradient(dt, new double[6]);
105 final FieldPVCoordinates<Gradient> actualPV = KeplerianMotionCartesianUtility.predictPositionVelocity(fieldDt,
106 fieldPosition, fieldVelocity, fieldMu);
107 final PVCoordinates expectedPV = KeplerianMotionCartesianUtility.predictPositionVelocity(dt, position,
108 velocity, mu);
109 comparePV(expectedPV, actualPV.toPVCoordinates());
110 final FieldOrbit<Gradient> fieldEquinoctialOrbit = OrbitType.EQUINOCTIAL.convertType(fieldOrbit);
111 final FieldOrbit<Gradient> shiftedOrbit = fieldEquinoctialOrbit.shiftedBy(fieldDt);
112 compareDerivatives(shiftedOrbit.getPVCoordinates(), actualPV);
113 }
114 }
115
116 private static void compareDerivatives(final FieldPVCoordinates<Gradient> expectedPV,
117 final FieldPVCoordinates<Gradient> actualPV) {
118
119 final double toleranceGradientPosition = 1e-6;
120 final double toleranceGradientVelocity = 1e-7;
121 for (int i = 0; i < 6; i++) {
122 Assertions.assertEquals(expectedPV.getPosition().getX().getPartialDerivative(i),
123 actualPV.getPosition().getX().getPartialDerivative(i), toleranceGradientPosition);
124 Assertions.assertEquals(expectedPV.getPosition().getY().getPartialDerivative(i),
125 actualPV.getPosition().getY().getPartialDerivative(i), toleranceGradientPosition);
126 Assertions.assertEquals(expectedPV.getPosition().getZ().getPartialDerivative(i),
127 actualPV.getPosition().getZ().getPartialDerivative(i), toleranceGradientPosition);
128 Assertions.assertEquals(expectedPV.getVelocity().getX().getPartialDerivative(i),
129 actualPV.getVelocity().getX().getPartialDerivative(i), toleranceGradientVelocity);
130 Assertions.assertEquals(expectedPV.getVelocity().getY().getPartialDerivative(i),
131 actualPV.getVelocity().getY().getPartialDerivative(i), toleranceGradientVelocity);
132 Assertions.assertEquals(expectedPV.getVelocity().getZ().getPartialDerivative(i),
133 actualPV.getVelocity().getZ().getPartialDerivative(i), toleranceGradientVelocity);
134 }
135 }
136
137 @Test
138 void testPredictPositionVelocityEllipticField() {
139
140 final ComplexField field = ComplexField.getInstance();
141 final double mu = 1.;
142 final Vector3D position = new Vector3D(6., 0., 1.);
143 final Vector3D velocity = new Vector3D(0.01, 0.1, 0.);
144 final Complex fieldMu = new Complex(mu);
145 final FieldVector3D<Complex> fieldPosition = new FieldVector3D<>(field, position);
146 final FieldVector3D<Complex> fieldVelocity = new FieldVector3D<>(field, velocity);
147
148 for (double dt = -10.; dt <= 10.; dt += 0.1) {
149 final FieldPVCoordinates<Complex> actualPV = KeplerianMotionCartesianUtility.predictPositionVelocity(new Complex(dt),
150 fieldPosition, fieldVelocity, fieldMu);
151 final PVCoordinates expectedPV = KeplerianMotionCartesianUtility.predictPositionVelocity(dt, position,
152 velocity, mu);
153 comparePV(expectedPV, actualPV.toPVCoordinates());
154 }
155 }
156
157 @Test
158 void testPredictPositionVelocityHyperbolicField() {
159
160 final ComplexField field = ComplexField.getInstance();
161 final double mu = 1.;
162 final Vector3D position = new Vector3D(6., 0., 2.);
163 final Vector3D velocity = new Vector3D(0.01, 1, 0.);
164 final Complex fieldMu = new Complex(mu);
165 final FieldVector3D<Complex> fieldPosition = new FieldVector3D<>(field, position);
166 final FieldVector3D<Complex> fieldVelocity = new FieldVector3D<>(field, velocity);
167
168 for (double dt = -10.; dt <= 10.; dt += 0.1) {
169 final FieldPVCoordinates<Complex> actualPV = KeplerianMotionCartesianUtility.predictPositionVelocity(new Complex(dt),
170 fieldPosition, fieldVelocity, fieldMu);
171 final PVCoordinates expectedPV = KeplerianMotionCartesianUtility.predictPositionVelocity(dt, position,
172 velocity, mu);
173 comparePV(expectedPV, actualPV.toPVCoordinates());
174 }
175 }
176
177 }