1 package org.orekit.propagation;
2
3 import org.hipparchus.geometry.euclidean.threed.Rotation;
4 import org.hipparchus.geometry.euclidean.threed.Vector3D;
5 import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
6 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
7 import org.hipparchus.util.FastMath;
8 import org.junit.jupiter.api.Assertions;
9 import org.junit.jupiter.api.BeforeEach;
10 import org.junit.jupiter.api.Test;
11 import org.orekit.Utils;
12 import org.orekit.attitudes.Attitude;
13 import org.orekit.forces.gravity.potential.GravityFieldFactory;
14 import org.orekit.forces.gravity.potential.SHMFormatReader;
15 import org.orekit.frames.FramesFactory;
16 import org.orekit.orbits.EquinoctialOrbit;
17 import org.orekit.orbits.Orbit;
18 import org.orekit.orbits.OrbitType;
19 import org.orekit.propagation.analytical.BrouwerLyddanePropagator;
20 import org.orekit.propagation.numerical.NumericalPropagator;
21 import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
22 import org.orekit.time.AbsoluteDate;
23 import org.orekit.utils.PVCoordinates;
24
25 class AdditionalDataProviderTest {
26 private static final double DURATION = 600.0;
27 private static final String STRING_BEFORE = "Let's go!";
28 private static final String STRING_AFTER = "Good job!";
29 private AbsoluteDate initDate;
30 private SpacecraftState initialState;
31 private AdaptiveStepsizeIntegrator integrator;
32
33 @BeforeEach
34 public void setUp() {
35 Utils.setDataRoot("regular-data:potential/shm-format");
36 GravityFieldFactory.addPotentialCoefficientsReader(new SHMFormatReader("^eigen_cg03c_coef$", false));
37 final double mu = GravityFieldFactory.getUnnormalizedProvider(0, 0).getMu();
38 final Vector3D position = new Vector3D(7.0e6, 1.0e6, 4.0e6);
39 final Vector3D velocity = new Vector3D(-500.0, 8000.0, 1000.0);
40 initDate = AbsoluteDate.J2000_EPOCH;
41 final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position, velocity), FramesFactory.getEME2000(), initDate, mu);
42 initialState = new SpacecraftState(orbit);
43 double[][] tolerance = ToleranceProvider.getDefaultToleranceProvider(0.001).getTolerances(orbit, OrbitType.EQUINOCTIAL);
44 integrator = new DormandPrince853Integrator(0.001, 200, tolerance[0], tolerance[1]);
45 integrator.setInitialStepSize(60);
46 }
47
48 @Test
49 public void testModifyMainState() {
50
51
52 final NumericalPropagator propagator = new NumericalPropagator(integrator);
53 propagator.setInitialState(initialState);
54
55
56 final MainStateModifier modifier = new MainStateModifier();
57
58
59 propagator.addAdditionalDataProvider(modifier);
60
61
62 final double dt = 600.0;
63 final SpacecraftState propagated = propagator.propagate(initDate.shiftedBy(dt));
64
65
66 Assertions.assertEquals(2 * SpacecraftState.DEFAULT_MASS, propagated.getMass(), 1.0e-12);
67 Assertions.assertEquals(FastMath.PI,
68 propagated.getAttitude().getRotation().getAngle(),
69 1.0e-15);
70
71 }
72
73 @Test
74 public void testIssue900Numerical() {
75
76
77 final NumericalPropagator propagator = new NumericalPropagator(integrator);
78 propagator.setInitialState(initialState);
79
80
81 final String name = "init";
82 final TimeDifferenceProvider provider = new TimeDifferenceProvider(name);
83 Assertions.assertFalse(provider.wasCalled());
84
85
86 propagator.addAdditionalDataProvider(provider);
87
88
89 final double dt = 600.0;
90 final SpacecraftState propagated = propagator.propagate(initDate.shiftedBy(dt));
91
92
93 Assertions.assertTrue(provider.wasCalled());
94 Assertions.assertEquals(dt, propagated.getAdditionalState(name)[0], 0.01);
95
96 }
97
98 @Test
99 public void testIssue900Dsst() {
100
101
102 final DSSTPropagator propagator = new DSSTPropagator(integrator);
103 propagator.setInitialState(initialState, PropagationType.MEAN);
104
105
106 final String name = "init";
107 final TimeDifferenceProvider provider = new TimeDifferenceProvider(name);
108 Assertions.assertFalse(provider.wasCalled());
109
110
111 propagator.addAdditionalDataProvider(provider);
112
113
114 final double dt = 600.0;
115 final SpacecraftState propagated = propagator.propagate(initialState.getDate().shiftedBy(dt));
116
117
118 Assertions.assertTrue(provider.wasCalled());
119 Assertions.assertEquals(dt, propagated.getAdditionalState(name)[0], 0.01);
120
121 }
122
123 @Test
124 public void testIssue900BrouwerLyddane() {
125
126
127 BrouwerLyddanePropagator propagator = new BrouwerLyddanePropagator(initialState.getOrbit(), Utils.defaultLaw(),
128 GravityFieldFactory.getUnnormalizedProvider(5, 0), BrouwerLyddanePropagator.M2);
129
130
131 final String name = "init";
132 final TimeDifferenceProvider provider = new TimeDifferenceProvider(name);
133 Assertions.assertFalse(provider.wasCalled());
134
135
136 propagator.addAdditionalDataProvider(provider);
137
138
139 final double dt = 600.0;
140 final SpacecraftState propagated = propagator.propagate(initialState.getDate().shiftedBy(dt));
141
142
143 Assertions.assertTrue(provider.wasCalled());
144 Assertions.assertEquals(dt, propagated.getAdditionalState(name)[0], 0.01);
145
146 }
147
148 @Test
149 public void testPropagateAdditionalStringData() {
150 final NumericalPropagator propagator = new NumericalPropagator(integrator);
151 propagator.setInitialState(initialState);
152
153 final MainStringDataModifier modifier = new MainStringDataModifier();
154 propagator.addAdditionalDataProvider(modifier);
155
156 final SpacecraftState propagated = propagator.propagate(initDate.shiftedBy(DURATION));
157 Assertions.assertEquals(STRING_AFTER, propagated.getAdditionalData(MainStringDataModifier.class.getSimpleName()));
158 }
159
160 @Test
161 public void testInterpolationAdditionalStringData() {
162 final NumericalPropagator propagator = new NumericalPropagator(integrator);
163 propagator.setInitialState(initialState);
164
165 final MainStringDataModifier modifier = new MainStringDataModifier();
166 propagator.addAdditionalDataProvider(modifier);
167 EphemerisGenerator generator = propagator.getEphemerisGenerator();
168 propagator.propagate(initDate.shiftedBy(DURATION));
169 BoundedPropagator ephemeris = generator.getGeneratedEphemeris();
170
171 Assertions.assertEquals(STRING_BEFORE, getAdditionalDataAt(ephemeris, initDate.shiftedBy(DURATION / 2 - 0.1)));
172 Assertions.assertEquals(STRING_AFTER, getAdditionalDataAt(ephemeris, initDate.shiftedBy(DURATION / 2)));
173 Assertions.assertEquals(STRING_AFTER, getAdditionalDataAt(ephemeris, initDate.shiftedBy(DURATION / 2 + 0.1)));
174 }
175
176 private Object getAdditionalDataAt(Propagator propagator, AbsoluteDate date) {
177 return propagator.propagate(date).getAdditionalData(MainStringDataModifier.class.getSimpleName());
178 }
179
180 private class MainStringDataModifier implements AdditionalDataProvider<String> {
181
182 private String value;
183
184 @Override
185 public void init(SpacecraftState initialState, AbsoluteDate target) {
186 value = target.getDate().isBefore(initDate.shiftedBy(DURATION / 2)) ? STRING_BEFORE : STRING_AFTER;
187 }
188
189 @Override
190 public String getAdditionalData(SpacecraftState state) {
191 return value;
192 }
193
194 @Override
195 public String getName() {
196 return MainStringDataModifier.class.getSimpleName();
197 }
198 }
199
200 private static class MainStateModifier extends AbstractStateModifier {
201
202 @Override
203 public SpacecraftState change(final SpacecraftState state) {
204 return new SpacecraftState(state.getOrbit(),
205 new Attitude(state.getDate(),
206 state.getFrame(),
207 new Rotation(0, 0, 0, 1, false),
208 Vector3D.ZERO,
209 Vector3D.ZERO),
210 2 * SpacecraftState.DEFAULT_MASS);
211 }
212 }
213
214 private static class TimeDifferenceProvider implements AdditionalDataProvider<double[]> {
215
216 private final String name;
217 private boolean called;
218 private double dt;
219
220 public TimeDifferenceProvider(final String name) {
221 this.name = name;
222 this.called = false;
223 this.dt = 0.0;
224 }
225
226 @Override
227 public void init(SpacecraftState initialState, AbsoluteDate target) {
228 this.called = true;
229 this.dt = target.durationFrom(initialState.getDate());
230 }
231
232 @Override
233 public String getName() {
234 return name;
235 }
236
237 @Override
238 public double[] getAdditionalData(SpacecraftState state) {
239 return new double[] {
240 dt
241 };
242 }
243
244 public boolean wasCalled() {
245 return called;
246 }
247
248 }
249
250 }