1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.orekit.bodies;
19
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
22 import org.hipparchus.analysis.differentiation.UnivariateDerivative1Field;
23 import org.hipparchus.complex.Complex;
24 import org.hipparchus.complex.ComplexField;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.Test;
31 import org.junit.jupiter.params.ParameterizedTest;
32 import org.junit.jupiter.params.provider.ValueSource;
33 import org.orekit.Utils;
34 import org.orekit.data.DataContext;
35 import org.orekit.forces.gravity.ThirdBodyAttraction;
36 import org.orekit.frames.Frame;
37 import org.orekit.frames.Frames;
38 import org.orekit.frames.FramesFactory;
39 import org.orekit.orbits.EquinoctialOrbit;
40 import org.orekit.orbits.PositionAngleType;
41 import org.orekit.propagation.SpacecraftState;
42 import org.orekit.propagation.numerical.NumericalPropagator;
43 import org.orekit.time.AbsoluteDate;
44 import org.orekit.time.DateTimeComponents;
45 import org.orekit.time.FieldAbsoluteDate;
46 import org.orekit.time.TimeScalesFactory;
47 import org.orekit.utils.Constants;
48 import org.orekit.utils.ExtendedPositionProvider;
49
50 class AnalyticalSolarPositionProviderTest {
51
52 @BeforeEach
53 void setUp() {
54 Utils.setDataRoot("regular-data");
55 }
56
57 @ParameterizedTest
58 @ValueSource(ints = {1, 2, 3, 4, 5})
59 void testGetPosition(final int month) {
60
61 final AbsoluteDate date = new AbsoluteDate(new DateTimeComponents(2000, month, 1, 0, 0, 0),
62 TimeScalesFactory.getUTC());
63 final AnalyticalSolarPositionProvider solarPositionProvider = new AnalyticalSolarPositionProvider();
64 final Frame frame = FramesFactory.getGCRF();
65
66 final Vector3D actualPosition = solarPositionProvider.getPosition(date, frame);
67
68 final CelestialBody celestialBody = CelestialBodyFactory.getSun();
69 final Vector3D expectedPosition = celestialBody.getPosition(date, frame);
70 Assertions.assertEquals(0., Vector3D.angle(expectedPosition, actualPosition), 5e-5);
71 Assertions.assertEquals(0., expectedPosition.subtract(actualPosition).getNorm(), 1e7);
72 }
73
74 @Test
75 void testGetPositionFieldVersusNonField() {
76
77 final AbsoluteDate date = new AbsoluteDate(new DateTimeComponents(2025, 1, 1, 0, 0, 0),
78 TimeScalesFactory.getUTC());
79 final DataContext dataContext = DataContext.getDefault();
80 final Frames frames = dataContext.getFrames();
81 final Frame frame = frames.getEME2000();
82 final AnalyticalSolarPositionProvider solarPositionProvider = new AnalyticalSolarPositionProvider(dataContext);
83 final FieldAbsoluteDate<Complex> fieldDate = new FieldAbsoluteDate<>(ComplexField.getInstance(), date);
84
85 final FieldVector3D<Complex> fieldPosition = solarPositionProvider.getPosition(fieldDate, frame);
86
87 final Vector3D expectedPosition = solarPositionProvider.getPosition(date, frame);
88 Assertions.assertEquals(expectedPosition, fieldPosition.toVector3D());
89 }
90
91 @Test
92 void testGetPositionFieldDate() {
93
94 final AbsoluteDate date = new AbsoluteDate(new DateTimeComponents(2025, 1, 1, 0, 0, 0),
95 TimeScalesFactory.getUTC());
96 final DataContext dataContext = DataContext.getDefault();
97 final Frames frames = dataContext.getFrames();
98 final Frame frame = frames.getGCRF();
99 final AnalyticalSolarPositionProvider solarPositionProvider = new AnalyticalSolarPositionProvider(dataContext);
100 final FieldAbsoluteDate<UnivariateDerivative1> fieldDate = new FieldAbsoluteDate<>(UnivariateDerivative1Field.getInstance(),
101 date).shiftedBy(new UnivariateDerivative1(0., 1.));
102
103 final FieldVector3D<UnivariateDerivative1> fieldPosition = solarPositionProvider.getPosition(fieldDate, frame);
104
105 Assertions.assertNotEquals(0., fieldPosition.getX().getFirstDerivative());
106 }
107
108 @Test
109 void testPropagation() {
110
111 final CelestialBody sun = CelestialBodyFactory.getSun();
112 final ExtendedPositionProvider positionProvider = new AnalyticalSolarPositionProvider();
113 final CelestialBody body = createCelestialBody(sun.getGM(), positionProvider);
114
115 final NumericalPropagator propagator = createPropagator(body);
116 final AbsoluteDate terminalDate = propagator.getInitialState().getDate().shiftedBy(1e6);
117 final SpacecraftState actualState = propagator.propagate(terminalDate);
118
119 final NumericalPropagator propagator2 = createPropagator(sun);
120 final SpacecraftState expectedState = propagator2.propagate(terminalDate);
121 Assertions.assertEquals(0., expectedState.getPosition().subtract(actualState.getPosition()).getNorm(), 1e-1);
122 }
123
124 private static CelestialBody createCelestialBody(final double mu, final ExtendedPositionProvider positionProvider) {
125 return new CelestialBody() {
126 @Override
127 public Frame getInertiallyOrientedFrame() {
128 return null;
129 }
130
131 @Override
132 public Frame getBodyOrientedFrame() {
133 return null;
134 }
135
136 @Override
137 public String getName() {
138 return "";
139 }
140
141 @Override
142 public double getGM() {
143 return mu;
144 }
145
146 @Override
147 public Vector3D getPosition(AbsoluteDate date, Frame frame) {
148 return positionProvider.getPosition(date, frame);
149 }
150
151 @Override
152 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPosition(FieldAbsoluteDate<T> date, Frame frame) {
153 return null;
154 }
155 };
156 }
157
158 private static NumericalPropagator createPropagator(final CelestialBody celestialBody) {
159 final NumericalPropagator propagator = new NumericalPropagator(new ClassicalRungeKuttaIntegrator(100));
160 final AbsoluteDate date = new AbsoluteDate(new DateTimeComponents(2000, 1, 1, 0, 0, 0),
161 TimeScalesFactory.getUTC());
162 final EquinoctialOrbit orbit = new EquinoctialOrbit(Constants.EGM96_EARTH_EQUATORIAL_RADIUS + 1000.e3,
163 0.1, 0.2, 0.3, 0.4, 5., PositionAngleType.ECCENTRIC, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);
164 propagator.setInitialState(new SpacecraftState(orbit));
165 propagator.addForceModel(new ThirdBodyAttraction(celestialBody));
166 return propagator;
167 }
168 }