1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.integration;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.ode.DenseOutputModel;
22 import org.hipparchus.ode.ODEStateAndDerivative;
23 import org.orekit.attitudes.AttitudeProvider;
24 import org.orekit.attitudes.AttitudeProviderModifier;
25 import org.orekit.errors.OrekitException;
26 import org.orekit.errors.OrekitMessages;
27 import org.orekit.frames.Frame;
28 import org.orekit.orbits.Orbit;
29 import org.orekit.propagation.AdditionalDataProvider;
30 import org.orekit.propagation.BoundedPropagator;
31 import org.orekit.propagation.PropagationType;
32 import org.orekit.propagation.SpacecraftState;
33 import org.orekit.propagation.analytical.AbstractAnalyticalPropagator;
34 import org.orekit.propagation.events.EventDetector;
35 import org.orekit.propagation.events.FieldEventDetector;
36 import org.orekit.time.AbsoluteDate;
37 import org.orekit.utils.DataDictionary;
38
39 import java.util.Arrays;
40 import java.util.List;
41 import java.util.stream.Stream;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class IntegratedEphemeris
74 extends AbstractAnalyticalPropagator implements BoundedPropagator {
75
76
77 private static final double EXTRAPOLATION_TOLERANCE = 1.0;
78
79
80 private final StateMapper mapper;
81
82
83
84
85
86
87
88 private final PropagationType type;
89
90
91 private final AbsoluteDate startDate;
92
93
94 private final AbsoluteDate minDate;
95
96
97 private final AbsoluteDate maxDate;
98
99
100 private final DenseOutputModel model;
101
102
103 private final DataDictionary unmanaged;
104
105
106
107
108 private final String[] equations;
109
110
111
112
113 private final int[] dimensions;
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public IntegratedEphemeris(final AbsoluteDate startDate,
130 final AbsoluteDate minDate, final AbsoluteDate maxDate,
131 final StateMapper mapper, final AttitudeProvider attitudeProvider,
132 final PropagationType type, final DenseOutputModel model,
133 final DataDictionary unmanaged,
134 final List<AdditionalDataProvider<?>> providers,
135 final String[] equations, final int[] dimensions) {
136
137 super(attitudeProvider);
138
139 this.startDate = startDate;
140 this.minDate = minDate;
141 this.maxDate = maxDate;
142 this.mapper = mapper;
143 this.type = type;
144 this.model = model;
145 this.unmanaged = unmanaged;
146
147
148 for (final AdditionalDataProvider<?> provider : providers) {
149 addAdditionalDataProvider(provider);
150 }
151
152 this.equations = equations.clone();
153 this.dimensions = dimensions.clone();
154
155
156 super.resetInitialState(getInitialState());
157
158
159 setAttitudeProvider(new AttitudeProviderModifier() {
160 @Override
161 public AttitudeProvider getUnderlyingAttitudeProvider() {
162 return attitudeProvider;
163 }
164
165 @Override
166 public Stream<EventDetector> getEventDetectors() {
167 return Stream.of();
168 }
169
170 @Override
171 public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(final Field<T> field) {
172 return Stream.of();
173 }
174 });
175 }
176
177
178
179
180
181 private ODEStateAndDerivative getInterpolatedState(final AbsoluteDate date) {
182
183
184
185 if (date.compareTo(minDate.shiftedBy(-EXTRAPOLATION_TOLERANCE)) < 0) {
186
187 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_BEFORE,
188 date, minDate, maxDate, minDate.durationFrom(date));
189 }
190 if (date.compareTo(maxDate.shiftedBy(EXTRAPOLATION_TOLERANCE)) > 0) {
191
192 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_AFTER,
193 date, minDate, maxDate, date.durationFrom(maxDate));
194 }
195
196 return model.getInterpolatedState(date.durationFrom(startDate));
197
198 }
199
200
201 @Override
202 public SpacecraftState basicPropagate(final AbsoluteDate date) {
203 final ODEStateAndDerivative os = getInterpolatedState(date);
204 SpacecraftState state = mapper.mapArrayToState(mapper.mapDoubleToDate(os.getTime(), date),
205 os.getPrimaryState(), os.getPrimaryDerivative(),
206 type);
207 for (DataDictionary.Entry initial : unmanaged.getData()) {
208 state = state.addAdditionalData(initial.getKey(), initial.getValue());
209 }
210 return state;
211 }
212
213
214 public Orbit propagateOrbit(final AbsoluteDate date) {
215 return basicPropagate(date).getOrbit();
216 }
217
218
219 protected double getMass(final AbsoluteDate date) {
220 return basicPropagate(date).getMass();
221 }
222
223
224
225
226 public AbsoluteDate getMinDate() {
227 return minDate;
228 }
229
230
231
232
233 public AbsoluteDate getMaxDate() {
234 return maxDate;
235 }
236
237 @Override
238 public Frame getFrame() {
239 return this.mapper.getFrame();
240 }
241
242
243 @Override
244 public void resetInitialState(final SpacecraftState state) {
245 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
246 }
247
248
249 protected void resetIntermediateState(final SpacecraftState state, final boolean forward) {
250 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
251 }
252
253
254 @Override
255 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
256 super.setAttitudeProvider(attitudeProvider);
257 if (mapper != null) {
258
259
260 mapper.setAttitudeProvider(attitudeProvider);
261 }
262 }
263
264
265 @Override
266 public SpacecraftState getInitialState() {
267 return updateAdditionalData(basicPropagate(getMinDate()));
268 }
269
270
271 @Override
272 public SpacecraftState updateAdditionalData(final SpacecraftState original) {
273
274 SpacecraftState updated = super.updateAdditionalData(original);
275
276 if (equations.length > 0) {
277 final ODEStateAndDerivative osd = getInterpolatedState(updated.getDate());
278 final double[] combinedState = osd.getSecondaryState(1);
279 final double[] combinedDerivative = osd.getSecondaryDerivative(1);
280 int index = 0;
281 for (int i = 0; i < equations.length; ++i) {
282 final double[] state = Arrays.copyOfRange(combinedState, index, index + dimensions[i]);
283 final double[] derivative = Arrays.copyOfRange(combinedDerivative, index, index + dimensions[i]);
284 updated = updated.
285 addAdditionalData(equations[i], state).
286 addAdditionalStateDerivative(equations[i], derivative);
287 index += dimensions[i];
288 }
289 }
290
291 return updated;
292
293 }
294
295 }