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