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