1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.List;
24 import java.util.PriorityQueue;
25 import java.util.Queue;
26
27 import org.hipparchus.CalculusFieldElement;
28 import org.hipparchus.Field;
29 import org.hipparchus.exception.MathRuntimeException;
30 import org.hipparchus.ode.events.Action;
31 import org.orekit.attitudes.AttitudeProvider;
32 import org.orekit.attitudes.FieldAttitude;
33 import org.orekit.errors.OrekitException;
34 import org.orekit.errors.OrekitInternalError;
35 import org.orekit.frames.Frame;
36 import org.orekit.orbits.FieldOrbit;
37 import org.orekit.propagation.BoundedPropagator;
38 import org.orekit.propagation.FieldAbstractPropagator;
39 import org.orekit.propagation.FieldAdditionalStateProvider;
40 import org.orekit.propagation.FieldBoundedPropagator;
41 import org.orekit.propagation.FieldEphemerisGenerator;
42 import org.orekit.propagation.FieldSpacecraftState;
43 import org.orekit.propagation.events.FieldEventDetector;
44 import org.orekit.propagation.events.FieldEventState;
45 import org.orekit.propagation.events.FieldEventState.EventOccurrence;
46 import org.orekit.propagation.sampling.FieldOrekitStepInterpolator;
47 import org.orekit.time.FieldAbsoluteDate;
48 import org.orekit.utils.FieldPVCoordinatesProvider;
49 import org.orekit.utils.ParameterDriver;
50 import org.orekit.utils.ParameterDriversProvider;
51 import org.orekit.utils.TimeStampedFieldPVCoordinates;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public abstract class FieldAbstractAnalyticalPropagator<T extends CalculusFieldElement<T>> extends FieldAbstractPropagator<T>
67 implements ParameterDriversProvider {
68
69
70 private FieldPVCoordinatesProvider<T> pvProvider;
71
72
73 private FieldAbsoluteDate<T> lastPropagationStart;
74
75
76 private FieldAbsoluteDate<T> lastPropagationEnd;
77
78
79 private boolean statesInitialized;
80
81
82 private boolean isLastStep;
83
84
85 private final Collection<FieldEventState<?, T>> eventsStates;
86
87
88
89
90
91 protected FieldAbstractAnalyticalPropagator(final Field<T> field, final AttitudeProvider attitudeProvider) {
92 super(field);
93 setAttitudeProvider(attitudeProvider);
94 pvProvider = new FieldLocalPVProvider();
95 lastPropagationStart = FieldAbsoluteDate.getPastInfinity(field);
96 lastPropagationEnd = FieldAbsoluteDate.getFutureInfinity(field);
97 statesInitialized = false;
98 eventsStates = new ArrayList<>();
99 }
100
101
102 @Override
103 public FieldEphemerisGenerator<T> getEphemerisGenerator() {
104 return () -> new FieldBoundedPropagatorView(lastPropagationStart, lastPropagationEnd);
105 }
106
107
108 public <D extends FieldEventDetector<T>> void addEventDetector(final D detector) {
109 eventsStates.add(new FieldEventState<>(detector));
110 }
111
112
113 @Override
114 public Collection<FieldEventDetector<T>> getEventsDetectors() {
115 final List<FieldEventDetector<T>> list = new ArrayList<>();
116 for (final FieldEventState<?, T> state : eventsStates) {
117 list.add(state.getEventDetector());
118 }
119 return Collections.unmodifiableCollection(list);
120 }
121
122
123 @Override
124 public void clearEventsDetectors() {
125 eventsStates.clear();
126 }
127
128 @Override
129 public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> start, final FieldAbsoluteDate<T> target) {
130 try {
131
132 initializePropagation();
133
134 lastPropagationStart = start;
135
136
137 initializeAdditionalStates(target);
138
139 final boolean isForward = target.compareTo(start) >= 0;
140 FieldSpacecraftState<T> state = updateAdditionalStates(basicPropagate(start));
141
142
143 for (final FieldEventState<?, T> es : eventsStates) {
144 es.init(state, target);
145 }
146
147
148 getMultiplexer().init(state, target);
149
150
151 statesInitialized = false;
152 isLastStep = false;
153 do {
154
155
156 final FieldSpacecraftState<T> previous = state;
157 final FieldSpacecraftState<T> current = updateAdditionalStates(basicPropagate(target));
158 final FieldBasicStepInterpolator interpolator =
159 new FieldBasicStepInterpolator(isForward, previous, current);
160
161
162 state = acceptStep(interpolator, target);
163
164
165
166 state = updateAdditionalStates(basicPropagate(state.getDate()));
167
168 } while (!isLastStep);
169
170
171 lastPropagationEnd = state.getDate();
172 setStartDate(state.getDate());
173 return state;
174
175 } catch (MathRuntimeException mrte) {
176 throw OrekitException.unwrap(mrte);
177 }
178 }
179
180
181
182
183
184
185
186 protected FieldSpacecraftState<T> acceptStep(final FieldBasicStepInterpolator interpolator,
187 final FieldAbsoluteDate<T> target)
188 throws MathRuntimeException {
189
190 FieldSpacecraftState<T> previous = interpolator.getPreviousState();
191 final FieldSpacecraftState<T> current = interpolator.getCurrentState();
192 FieldBasicStepInterpolator restricted = interpolator;
193
194
195 if (!statesInitialized) {
196
197 if (!eventsStates.isEmpty()) {
198
199 for (final FieldEventState<?, T> state : eventsStates) {
200 state.reinitializeBegin(interpolator);
201 }
202 }
203
204 statesInitialized = true;
205
206 }
207
208
209 final int orderingSign = interpolator.isForward() ? +1 : -1;
210 final Queue<FieldEventState<?, T>> occurringEvents = new PriorityQueue<>(new Comparator<FieldEventState<?, T>>() {
211
212 @Override
213 public int compare(final FieldEventState<?, T> es0, final FieldEventState<?, T> es1) {
214 return orderingSign * es0.getEventDate().compareTo(es1.getEventDate());
215 }
216 });
217
218 boolean doneWithStep = false;
219 resetEvents:
220 do {
221
222
223 occurringEvents.clear();
224 for (final FieldEventState<?, T> state : eventsStates) {
225 if (state.evaluateStep(interpolator)) {
226
227 occurringEvents.add(state);
228 }
229 }
230
231
232 do {
233
234 eventLoop:
235 while (!occurringEvents.isEmpty()) {
236
237
238 final FieldEventState<?, T> currentEvent = occurringEvents.poll();
239
240
241 FieldSpacecraftState<T> eventState = restricted.getInterpolatedState(currentEvent.getEventDate());
242
243
244 restricted = restricted.restrictStep(previous, eventState);
245
246
247 for (final FieldEventState<?, T> state : eventsStates) {
248 if (state != currentEvent && state.tryAdvance(eventState, interpolator)) {
249
250
251 occurringEvents.remove(state);
252
253 occurringEvents.add(state);
254
255 occurringEvents.add(currentEvent);
256 continue eventLoop;
257 }
258 }
259
260
261
262 getMultiplexer().handleStep(restricted);
263
264
265 final EventOccurrence<T> occurrence = currentEvent.doEvent(eventState);
266 final Action action = occurrence.getAction();
267 isLastStep = action == Action.STOP;
268 if (isLastStep) {
269
270
271
272
273 final FieldSpacecraftState<T> savedState = eventState;
274 eventState = interpolator.getInterpolatedState(occurrence.getStopDate());
275 restricted = restricted.restrictStep(savedState, eventState);
276
277
278 getMultiplexer().handleStep(restricted);
279 getMultiplexer().finish(restricted.getCurrentState());
280
281 }
282
283 if (isLastStep) {
284
285 return eventState;
286 }
287
288 if (action == Action.RESET_DERIVATIVES || action == Action.RESET_STATE) {
289
290
291 final FieldSpacecraftState<T> resetState = occurrence.getNewState();
292 resetIntermediateState(resetState, interpolator.isForward());
293 return resetState;
294 }
295
296
297
298 previous = eventState;
299 restricted = new FieldBasicStepInterpolator(restricted.isForward(), eventState, current);
300
301 if (action == Action.RESET_EVENTS) {
302 continue resetEvents;
303 }
304
305
306
307 if (currentEvent.evaluateStep(restricted)) {
308
309 occurringEvents.add(currentEvent);
310 }
311
312 }
313
314
315
316
317
318
319
320 for (final FieldEventState<?, T> state : eventsStates) {
321 if (state.tryAdvance(current, interpolator)) {
322 occurringEvents.add(state);
323 }
324 }
325
326 } while (!occurringEvents.isEmpty());
327
328 doneWithStep = true;
329 } while (!doneWithStep);
330
331 isLastStep = target.equals(current.getDate());
332
333
334 getMultiplexer().handleStep(restricted);
335 if (isLastStep) {
336 getMultiplexer().finish(restricted.getCurrentState());
337 }
338
339 return current;
340
341 }
342
343
344
345
346
347 protected abstract T getMass(FieldAbsoluteDate<T> date);
348
349
350
351
352 public FieldPVCoordinatesProvider<T> getPvProvider() {
353 return pvProvider;
354 }
355
356
357
358
359
360
361 protected abstract void resetIntermediateState(FieldSpacecraftState<T> state, boolean forward);
362
363
364
365
366
367
368 protected abstract FieldOrbit<T> propagateOrbit(FieldAbsoluteDate<T> date, T[] parameters);
369
370
371
372
373
374
375
376
377
378 protected FieldSpacecraftState<T> basicPropagate(final FieldAbsoluteDate<T> date) {
379 try {
380
381
382 final FieldOrbit<T> orbit = propagateOrbit(date, getParameters(date.getField(), date.getDate()));
383
384
385 final FieldAttitude<T> attitude =
386 getAttitudeProvider().getAttitude(pvProvider, date, orbit.getFrame());
387
388
389 return new FieldSpacecraftState<>(orbit, attitude, getMass(date));
390
391 } catch (OrekitException oe) {
392 throw new OrekitException(oe);
393 }
394 }
395
396
397 private class FieldLocalPVProvider implements FieldPVCoordinatesProvider<T> {
398
399
400 @Override
401 public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date, final Frame frame) {
402 return propagateOrbit(date, getParameters(date.getField(), date)).getPVCoordinates(frame);
403 }
404
405 }
406
407
408 private class FieldBoundedPropagatorView extends FieldAbstractAnalyticalPropagator<T>
409 implements FieldBoundedPropagator<T> {
410
411
412 private final FieldAbsoluteDate<T> minDate;
413
414
415 private final FieldAbsoluteDate<T> maxDate;
416
417
418
419
420
421 FieldBoundedPropagatorView(final FieldAbsoluteDate<T> startDate, final FieldAbsoluteDate<T> endDate) {
422 super(startDate.durationFrom(endDate).getField(), FieldAbstractAnalyticalPropagator.this.getAttitudeProvider());
423 super.resetInitialState(FieldAbstractAnalyticalPropagator.this.getInitialState());
424 if (startDate.compareTo(endDate) <= 0) {
425 minDate = startDate;
426 maxDate = endDate;
427 } else {
428 minDate = endDate;
429 maxDate = startDate;
430 }
431
432 try {
433
434 for (FieldAdditionalStateProvider<T> provider : FieldAbstractAnalyticalPropagator.this.getAdditionalStateProviders()) {
435 addAdditionalStateProvider(provider);
436 }
437 } catch (OrekitException oe) {
438
439
440 throw new OrekitInternalError(null);
441 }
442
443 }
444
445
446 @Override
447 public FieldAbsoluteDate<T> getMinDate() {
448 return minDate;
449 }
450
451
452 @Override
453 public FieldAbsoluteDate<T> getMaxDate() {
454 return maxDate;
455 }
456
457
458 @Override
459 protected FieldOrbit<T> propagateOrbit(final FieldAbsoluteDate<T> target, final T[] parameters) {
460 return FieldAbstractAnalyticalPropagator.this.propagateOrbit(target, parameters);
461 }
462
463
464 @Override
465 public T getMass(final FieldAbsoluteDate<T> date) {
466 return FieldAbstractAnalyticalPropagator.this.getMass(date);
467 }
468
469
470 @Override
471 public void resetInitialState(final FieldSpacecraftState<T> state) {
472 super.resetInitialState(state);
473 FieldAbstractAnalyticalPropagator.this.resetInitialState(state);
474 }
475
476
477 @Override
478 protected void resetIntermediateState(final FieldSpacecraftState<T> state, final boolean forward) {
479 FieldAbstractAnalyticalPropagator.this.resetIntermediateState(state, forward);
480 }
481
482
483 @Override
484 public FieldSpacecraftState<T> getInitialState() {
485 return FieldAbstractAnalyticalPropagator.this.getInitialState();
486 }
487
488
489 @Override
490 public Frame getFrame() {
491 return FieldAbstractAnalyticalPropagator.this.getFrame();
492 }
493
494
495 @Override
496 public List<ParameterDriver> getParametersDrivers() {
497 return FieldAbstractAnalyticalPropagator.this.getParametersDrivers();
498 }
499 }
500
501
502 private class FieldBasicStepInterpolator implements FieldOrekitStepInterpolator<T> {
503
504
505 private final FieldSpacecraftState<T> previousState;
506
507
508 private final FieldSpacecraftState<T> currentState;
509
510
511 private final boolean forward;
512
513
514
515
516
517
518 FieldBasicStepInterpolator(final boolean isForward,
519 final FieldSpacecraftState<T> previousState,
520 final FieldSpacecraftState<T> currentState) {
521 this.forward = isForward;
522 this.previousState = previousState;
523 this.currentState = currentState;
524 }
525
526
527 @Override
528 public FieldSpacecraftState<T> getPreviousState() {
529 return previousState;
530 }
531
532
533 @Override
534 public FieldSpacecraftState<T> getCurrentState() {
535 return currentState;
536 }
537
538
539 @Override
540 public FieldSpacecraftState<T> getInterpolatedState(final FieldAbsoluteDate<T> date) {
541
542
543 final FieldSpacecraftState<T> basicState = basicPropagate(date);
544
545
546 return updateAdditionalStates(basicState);
547
548 }
549
550
551 @Override
552 public boolean isForward() {
553 return forward;
554 }
555
556
557 @Override
558 public FieldBasicStepInterpolator restrictStep(final FieldSpacecraftState<T> newPreviousState,
559 final FieldSpacecraftState<T> newCurrentState) {
560 return new FieldBasicStepInterpolator(forward, newPreviousState, newCurrentState);
561 }
562
563 }
564
565 }