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 java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.hipparchus.exception.MathRuntimeException;
27 import org.hipparchus.ode.DenseOutputModel;
28 import org.hipparchus.ode.EquationsMapper;
29 import org.hipparchus.ode.ExpandableODE;
30 import org.hipparchus.ode.ODEIntegrator;
31 import org.hipparchus.ode.ODEState;
32 import org.hipparchus.ode.ODEStateAndDerivative;
33 import org.hipparchus.ode.OrdinaryDifferentialEquation;
34 import org.hipparchus.ode.SecondaryODE;
35 import org.hipparchus.ode.events.Action;
36 import org.hipparchus.ode.events.ODEEventHandler;
37 import org.hipparchus.ode.sampling.AbstractODEStateInterpolator;
38 import org.hipparchus.ode.sampling.ODEStateInterpolator;
39 import org.hipparchus.ode.sampling.ODEStepHandler;
40 import org.hipparchus.util.Precision;
41 import org.orekit.attitudes.AttitudeProvider;
42 import org.orekit.errors.OrekitException;
43 import org.orekit.errors.OrekitIllegalStateException;
44 import org.orekit.errors.OrekitInternalError;
45 import org.orekit.errors.OrekitMessages;
46 import org.orekit.frames.Frame;
47 import org.orekit.orbits.OrbitType;
48 import org.orekit.orbits.PositionAngle;
49 import org.orekit.propagation.AbstractPropagator;
50 import org.orekit.propagation.BoundedPropagator;
51 import org.orekit.propagation.PropagationType;
52 import org.orekit.propagation.SpacecraftState;
53 import org.orekit.propagation.events.EventDetector;
54 import org.orekit.propagation.sampling.OrekitStepHandler;
55 import org.orekit.propagation.sampling.OrekitStepInterpolator;
56 import org.orekit.time.AbsoluteDate;
57
58
59
60
61
62
63 public abstract class AbstractIntegratedPropagator extends AbstractPropagator {
64
65
66 private final List<EventDetector> detectors;
67
68
69 private final ODEIntegrator integrator;
70
71
72 private ModeHandler modeHandler;
73
74
75 private List<AdditionalEquations> additionalEquations;
76
77
78 private int calls;
79
80
81 private StateMapper stateMapper;
82
83
84 private EquationsMapper equationsMapper;
85
86
87 private boolean resetAtEnd;
88
89
90
91
92
93
94
95 private PropagationType propagationType;
96
97
98
99
100
101 protected AbstractIntegratedPropagator(final ODEIntegrator integrator, final PropagationType propagationType) {
102 detectors = new ArrayList<EventDetector>();
103 additionalEquations = new ArrayList<AdditionalEquations>();
104 this.integrator = integrator;
105 this.propagationType = propagationType;
106 this.resetAtEnd = true;
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121 public void setResetAtEnd(final boolean resetAtEnd) {
122 this.resetAtEnd = resetAtEnd;
123 }
124
125
126 protected void initMapper() {
127 stateMapper = createMapper(null, Double.NaN, null, null, null, null);
128 }
129
130
131 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
132 super.setAttitudeProvider(attitudeProvider);
133 stateMapper = createMapper(stateMapper.getReferenceDate(), stateMapper.getMu(),
134 stateMapper.getOrbitType(), stateMapper.getPositionAngleType(),
135 attitudeProvider, stateMapper.getFrame());
136 }
137
138
139
140
141
142
143 protected void setOrbitType(final OrbitType orbitType) {
144 stateMapper = createMapper(stateMapper.getReferenceDate(), stateMapper.getMu(),
145 orbitType, stateMapper.getPositionAngleType(),
146 stateMapper.getAttitudeProvider(), stateMapper.getFrame());
147 }
148
149
150
151
152
153
154 protected OrbitType getOrbitType() {
155 return stateMapper.getOrbitType();
156 }
157
158
159
160
161
162 protected PropagationType isMeanOrbit() {
163 return propagationType;
164 }
165
166
167
168
169
170
171
172
173
174
175 protected void setPositionAngleType(final PositionAngle positionAngleType) {
176 stateMapper = createMapper(stateMapper.getReferenceDate(), stateMapper.getMu(),
177 stateMapper.getOrbitType(), positionAngleType,
178 stateMapper.getAttitudeProvider(), stateMapper.getFrame());
179 }
180
181
182
183
184 protected PositionAngle getPositionAngleType() {
185 return stateMapper.getPositionAngleType();
186 }
187
188
189
190
191 public void setMu(final double mu) {
192 stateMapper = createMapper(stateMapper.getReferenceDate(), mu,
193 stateMapper.getOrbitType(), stateMapper.getPositionAngleType(),
194 stateMapper.getAttitudeProvider(), stateMapper.getFrame());
195 }
196
197
198
199
200
201 public double getMu() {
202 return stateMapper.getMu();
203 }
204
205
206
207
208
209
210 public int getCalls() {
211 return calls;
212 }
213
214
215 @Override
216 public boolean isAdditionalStateManaged(final String name) {
217
218
219 if (super.isAdditionalStateManaged(name)) {
220 return true;
221 }
222
223
224 for (final AdditionalEquations equation : additionalEquations) {
225 if (equation.getName().equals(name)) {
226 return true;
227 }
228 }
229
230 return false;
231 }
232
233
234 @Override
235 public String[] getManagedAdditionalStates() {
236 final String[] alreadyIntegrated = super.getManagedAdditionalStates();
237 final String[] managed = new String[alreadyIntegrated.length + additionalEquations.size()];
238 System.arraycopy(alreadyIntegrated, 0, managed, 0, alreadyIntegrated.length);
239 for (int i = 0; i < additionalEquations.size(); ++i) {
240 managed[i + alreadyIntegrated.length] = additionalEquations.get(i).getName();
241 }
242 return managed;
243 }
244
245
246
247
248 public void addAdditionalEquations(final AdditionalEquations additional) {
249
250
251 if (isAdditionalStateManaged(additional.getName())) {
252
253 throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
254 additional.getName());
255 }
256
257
258 additionalEquations.add(additional);
259
260 }
261
262
263 public void addEventDetector(final EventDetector detector) {
264 detectors.add(detector);
265 }
266
267
268 public Collection<EventDetector> getEventsDetectors() {
269 return Collections.unmodifiableCollection(detectors);
270 }
271
272
273 public void clearEventsDetectors() {
274 detectors.clear();
275 }
276
277
278
279 protected void setUpUserEventDetectors() {
280 for (final EventDetector detector : detectors) {
281 setUpEventDetector(integrator, detector);
282 }
283 }
284
285
286
287
288
289 protected void setUpEventDetector(final ODEIntegrator integ, final EventDetector detector) {
290 integ.addEventHandler(new AdaptedEventDetector(detector),
291 detector.getMaxCheckInterval(),
292 detector.getThreshold(),
293 detector.getMaxIterationCount());
294 }
295
296
297
298
299
300
301
302 public void setSlaveMode() {
303 super.setSlaveMode();
304 if (integrator != null) {
305 integrator.clearStepHandlers();
306 }
307 modeHandler = null;
308 }
309
310
311
312
313
314
315
316 public void setMasterMode(final OrekitStepHandler handler) {
317 super.setMasterMode(handler);
318 integrator.clearStepHandlers();
319 final AdaptedStepHandler wrapped = new AdaptedStepHandler(handler);
320 integrator.addStepHandler(wrapped);
321 modeHandler = wrapped;
322 }
323
324
325
326
327
328
329
330 public void setEphemerisMode() {
331 super.setEphemerisMode();
332 integrator.clearStepHandlers();
333 final EphemerisModeHandler ephemeris = new EphemerisModeHandler();
334 modeHandler = ephemeris;
335 integrator.addStepHandler(ephemeris);
336 }
337
338
339
340
341
342
343
344
345 @Override
346 public void setEphemerisMode(final OrekitStepHandler handler) {
347 super.setEphemerisMode();
348 integrator.clearStepHandlers();
349 final EphemerisModeHandler ephemeris = new EphemerisModeHandler(handler);
350 modeHandler = ephemeris;
351 integrator.addStepHandler(ephemeris);
352 }
353
354
355 public BoundedPropagator getGeneratedEphemeris()
356 throws IllegalStateException {
357 if (getMode() != EPHEMERIS_GENERATION_MODE) {
358 throw new OrekitIllegalStateException(OrekitMessages.PROPAGATOR_NOT_IN_EPHEMERIS_GENERATION_MODE);
359 }
360 return ((EphemerisModeHandler) modeHandler).getEphemeris();
361 }
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379 protected abstract StateMapper createMapper(AbsoluteDate referenceDate, double mu,
380 OrbitType orbitType, PositionAngle positionAngleType,
381 AttitudeProvider attitudeProvider, Frame frame);
382
383
384
385
386
387 protected abstract MainStateEquations getMainStateEquations(ODEIntegrator integ);
388
389
390 public SpacecraftState propagate(final AbsoluteDate target) {
391 if (getStartDate() == null) {
392 if (getInitialState() == null) {
393 throw new OrekitException(OrekitMessages.INITIAL_STATE_NOT_SPECIFIED_FOR_ORBIT_PROPAGATION);
394 }
395 setStartDate(getInitialState().getDate());
396 }
397 return propagate(getStartDate(), target);
398 }
399
400
401 public SpacecraftState propagate(final AbsoluteDatebsoluteDate">AbsoluteDate tStart, final AbsoluteDate tEnd) {
402
403 if (getInitialState() == null) {
404 throw new OrekitException(OrekitMessages.INITIAL_STATE_NOT_SPECIFIED_FOR_ORBIT_PROPAGATION);
405 }
406
407 if (!tStart.equals(getInitialState().getDate())) {
408
409
410 propagate(tStart, false);
411 }
412
413
414 return propagate(tEnd, true);
415
416 }
417
418
419
420
421
422
423 protected SpacecraftState propagate(final AbsoluteDate tEnd, final boolean activateHandlers) {
424 try {
425
426 initializePropagation();
427
428 if (getInitialState().getDate().equals(tEnd)) {
429
430 return getInitialState();
431 }
432
433
434 stateMapper = createMapper(getInitialState().getDate(), stateMapper.getMu(),
435 stateMapper.getOrbitType(), stateMapper.getPositionAngleType(),
436 stateMapper.getAttitudeProvider(), getInitialState().getFrame());
437
438
439 if (Double.isNaN(getMu())) {
440 setMu(getInitialState().getMu());
441 }
442
443 if (getInitialState().getMass() <= 0.0) {
444 throw new OrekitException(OrekitMessages.SPACECRAFT_MASS_BECOMES_NEGATIVE,
445 getInitialState().getMass());
446 }
447
448 integrator.clearEventHandlers();
449
450
451 if (activateHandlers) {
452 setUpUserEventDetectors();
453 }
454
455
456 final SpacecraftState initialIntegrationState = getInitialIntegrationState();
457 final ODEState mathInitialState = createInitialState(initialIntegrationState);
458 final ExpandableODE mathODE = createODE(integrator, mathInitialState);
459 equationsMapper = mathODE.getMapper();
460
461
462 if (modeHandler != null) {
463 modeHandler.initialize(activateHandlers, tEnd);
464 }
465
466
467 final ODEStateAndDerivative mathFinalState;
468 beforeIntegration(initialIntegrationState, tEnd);
469 mathFinalState = integrator.integrate(mathODE, mathInitialState,
470 tEnd.durationFrom(getInitialState().getDate()));
471 afterIntegration();
472
473
474 SpacecraftState finalState =
475 stateMapper.mapArrayToState(stateMapper.mapDoubleToDate(mathFinalState.getTime(),
476 tEnd),
477 mathFinalState.getPrimaryState(),
478 mathFinalState.getPrimaryDerivative(),
479 propagationType);
480
481 finalState = updateAdditionalStates(finalState);
482 for (int i = 0; i < additionalEquations.size(); ++i) {
483 final double[] secondary = mathFinalState.getSecondaryState(i + 1);
484 finalState = finalState.addAdditionalState(additionalEquations.get(i).getName(),
485 secondary);
486 }
487 if (resetAtEnd) {
488 resetInitialState(finalState);
489 setStartDate(finalState.getDate());
490 }
491
492 return finalState;
493
494 } catch (MathRuntimeException mre) {
495 throw OrekitException.unwrap(mre);
496 }
497 }
498
499
500
501
502 protected SpacecraftState getInitialIntegrationState() {
503 return getInitialState();
504 }
505
506
507
508
509
510 private ODEState createInitialState(final SpacecraftState initialState) {
511
512
513 final double[] primary = new double[getBasicDimension()];
514 stateMapper.mapStateToArray(initialState, primary, null);
515
516
517 final double[][] secondary = new double[additionalEquations.size()][];
518 for (int i = 0; i < additionalEquations.size(); ++i) {
519 final AdditionalEquations additional = additionalEquations.get(i);
520 secondary[i] = initialState.getAdditionalState(additional.getName());
521 }
522
523 return new ODEState(0.0, primary, secondary);
524
525 }
526
527
528
529
530
531
532 private ExpandableODE createODE(final ODEIntegrator integ,
533 final ODEState mathInitialState) {
534
535 final ExpandableODE ode =
536 new ExpandableODE(new ConvertedMainStateEquations(getMainStateEquations(integ)));
537
538
539 for (int i = 0; i < additionalEquations.size(); ++i) {
540 final AdditionalEquations additional = additionalEquations.get(i);
541 final SecondaryODE secondary =
542 new ConvertedSecondaryStateEquations(additional,
543 mathInitialState.getSecondaryStateDimension(i + 1));
544 ode.addSecondaryEquations(secondary);
545 }
546
547 return ode;
548
549 }
550
551
552
553
554
555
556
557
558 protected void beforeIntegration(final SpacecraftState initialState,
559 final AbsoluteDate tEnd) {
560
561 }
562
563
564
565
566
567
568 protected void afterIntegration() {
569
570 }
571
572
573
574
575 public int getBasicDimension() {
576 return 7;
577
578 }
579
580
581
582
583 protected ODEIntegrator getIntegrator() {
584 return integrator;
585 }
586
587
588
589
590
591
592
593 private SpacecraftState getCompleteState(final double t, final double[] y, final double[] yDot) {
594
595
596 SpacecraftState state = stateMapper.mapArrayToState(t, y, yDot, propagationType);
597
598
599 state = updateAdditionalStates(state);
600
601
602 if (!additionalEquations.isEmpty()) {
603
604 for (int i = 0; i < additionalEquations.size(); ++i) {
605 state = state.addAdditionalState(additionalEquations.get(i).getName(),
606 equationsMapper.extractEquationData(i + 1, y));
607 }
608
609 }
610
611 return state;
612
613 }
614
615
616 public interface MainStateEquations {
617
618
619
620
621
622
623
624
625
626
627
628 default void init(final SpacecraftState initialState, final AbsoluteDate target) {
629 }
630
631
632
633
634
635 double[] computeDerivatives(SpacecraftState state);
636
637 }
638
639
640 private class ConvertedMainStateEquations implements OrdinaryDifferentialEquation {
641
642
643 private final MainStateEquations main;
644
645
646
647
648 ConvertedMainStateEquations(final MainStateEquations main) {
649 this.main = main;
650 calls = 0;
651 }
652
653
654 public int getDimension() {
655 return getBasicDimension();
656 }
657
658 @Override
659 public void init(final double t0, final double[] y0, final double finalTime) {
660
661 SpacecraftState initialState = stateMapper.mapArrayToState(t0, y0, null, PropagationType.MEAN);
662 initialState = updateAdditionalStates(initialState);
663 final AbsoluteDate target = stateMapper.mapDoubleToDate(finalTime);
664 main.init(initialState, target);
665 }
666
667
668 public double[] computeDerivatives(final double t, final double[] y) {
669
670
671 ++calls;
672
673
674 SpacecraftState currentState = stateMapper.mapArrayToState(t, y, null, PropagationType.MEAN);
675 currentState = updateAdditionalStates(currentState);
676
677
678 return main.computeDerivatives(currentState);
679
680 }
681
682 }
683
684
685 private class ConvertedSecondaryStateEquations implements SecondaryODE {
686
687
688 private final AdditionalEquations equations;
689
690
691 private final int dimension;
692
693
694
695
696
697 ConvertedSecondaryStateEquations(final AdditionalEquations equations,
698 final int dimension) {
699 this.equations = equations;
700 this.dimension = dimension;
701 }
702
703
704 @Override
705 public int getDimension() {
706 return dimension;
707 }
708
709
710 @Override
711 public void init(final double t0, final double[] primary0,
712 final double[] secondary0, final double finalTime) {
713
714 SpacecraftState initialState = stateMapper.mapArrayToState(t0, primary0, null, PropagationType.MEAN);
715 initialState = updateAdditionalStates(initialState);
716 initialState = initialState.addAdditionalState(equations.getName(), secondary0);
717 final AbsoluteDate target = stateMapper.mapDoubleToDate(finalTime);
718 equations.init(initialState, target);
719
720 }
721
722
723 @Override
724 public double[] computeDerivatives(final double t, final double[] primary,
725 final double[] primaryDot, final double[] secondary) {
726
727
728 SpacecraftState currentState = stateMapper.mapArrayToState(t, primary, primaryDot, PropagationType.MEAN);
729 currentState = updateAdditionalStates(currentState);
730 currentState = currentState.addAdditionalState(equations.getName(), secondary);
731
732
733 final double[] secondaryDot = new double[secondary.length];
734 final double[] additionalMainDot =
735 equations.computeDerivatives(currentState, secondaryDot);
736 if (additionalMainDot != null) {
737
738 for (int i = 0; i < additionalMainDot.length; ++i) {
739 primaryDot[i] += additionalMainDot[i];
740 }
741 }
742
743 return secondaryDot;
744
745 }
746
747 }
748
749
750
751
752
753 private class AdaptedEventDetector implements ODEEventHandler {
754
755
756 private final EventDetector detector;
757
758
759 private double lastT;
760
761
762 private double lastG;
763
764
765
766
767 AdaptedEventDetector(final EventDetector detector) {
768 this.detector = detector;
769 this.lastT = Double.NaN;
770 this.lastG = Double.NaN;
771 }
772
773
774 public void init(final ODEStateAndDerivative s0, final double t) {
775 detector.init(getCompleteState(s0.getTime(), s0.getCompleteState(), s0.getCompleteDerivative()),
776 stateMapper.mapDoubleToDate(t));
777 this.lastT = Double.NaN;
778 this.lastG = Double.NaN;
779 }
780
781
782 public double g(final ODEStateAndDerivative s) {
783 if (!Precision.equals(lastT, s.getTime(), 0)) {
784 lastT = s.getTime();
785 lastG = detector.g(getCompleteState(s.getTime(), s.getCompleteState(), s.getCompleteDerivative()));
786 }
787 return lastG;
788 }
789
790
791 public Action eventOccurred(final ODEStateAndDerivative s, final boolean increasing) {
792 return detector.eventOccurred(
793 getCompleteState(
794 s.getTime(),
795 s.getCompleteState(),
796 s.getCompleteDerivative()),
797 increasing);
798 }
799
800
801 public ODEState resetState(final ODEStateAndDerivative s) {
802
803 final SpacecraftState oldState = getCompleteState(s.getTime(), s.getCompleteState(), s.getCompleteDerivative());
804 final SpacecraftState newState = detector.resetState(oldState);
805 stateChanged(newState);
806
807
808 final double[] primary = new double[s.getPrimaryStateDimension()];
809 stateMapper.mapStateToArray(newState, primary, null);
810
811
812 final double[][] secondary = new double[additionalEquations.size()][];
813 for (int i = 0; i < additionalEquations.size(); ++i) {
814 secondary[i] = newState.getAdditionalState(additionalEquations.get(i).getName());
815 }
816
817 return new ODEState(newState.getDate().durationFrom(getStartDate()),
818 primary, secondary);
819
820 }
821
822 }
823
824
825
826
827
828 private class AdaptedStepHandler implements ODEStepHandler, ModeHandler {
829
830
831 private final OrekitStepHandler handler;
832
833
834 private boolean activate;
835
836
837
838
839 AdaptedStepHandler(final OrekitStepHandler handler) {
840 this.handler = handler;
841 }
842
843
844 public void initialize(final boolean activateHandlers,
845 final AbsoluteDate targetDate) {
846 this.activate = activateHandlers;
847 }
848
849
850 public void init(final ODEStateAndDerivative s0, final double t) {
851 if (activate) {
852 handler.init(getCompleteState(s0.getTime(), s0.getCompleteState(), s0.getCompleteDerivative()),
853 stateMapper.mapDoubleToDate(t));
854 }
855 }
856
857
858 public void handleStep(final ODEStateInterpolator interpolator, final boolean isLast) {
859 if (activate) {
860 handler.handleStep(new AdaptedStepInterpolator(interpolator), isLast);
861 }
862 }
863
864 }
865
866
867
868
869
870 private class AdaptedStepInterpolator implements OrekitStepInterpolator {
871
872
873 private final ODEStateInterpolator mathInterpolator;
874
875
876
877
878 AdaptedStepInterpolator(final ODEStateInterpolator mathInterpolator) {
879 this.mathInterpolator = mathInterpolator;
880 }
881
882
883 @Override
884 public SpacecraftState getPreviousState() {
885 return convert(mathInterpolator.getPreviousState());
886 }
887
888
889 @Override
890 public boolean isPreviousStateInterpolated() {
891 return mathInterpolator.isPreviousStateInterpolated();
892 }
893
894
895 @Override
896 public SpacecraftState getCurrentState() {
897 return convert(mathInterpolator.getCurrentState());
898 }
899
900
901 @Override
902 public boolean isCurrentStateInterpolated() {
903 return mathInterpolator.isCurrentStateInterpolated();
904 }
905
906
907 @Override
908 public SpacecraftState getInterpolatedState(final AbsoluteDate date) {
909 return convert(mathInterpolator.getInterpolatedState(date.durationFrom(stateMapper.getReferenceDate())));
910 }
911
912
913
914
915
916 private SpacecraftState convert(final ODEStateAndDerivative os) {
917
918 SpacecraftState s =
919 stateMapper.mapArrayToState(os.getTime(),
920 os.getPrimaryState(),
921 os.getPrimaryDerivative(),
922 propagationType);
923 s = updateAdditionalStates(s);
924 for (int i = 0; i < additionalEquations.size(); ++i) {
925 final double[] secondary = os.getSecondaryState(i + 1);
926 s = s.addAdditionalState(additionalEquations.get(i).getName(), secondary);
927 }
928
929 return s;
930
931 }
932
933
934
935
936
937 private ODEStateAndDerivative convert(final SpacecraftState state) {
938
939
940 final double[] primary = new double[getBasicDimension()];
941 final double[] primaryDot = new double[getBasicDimension()];
942 stateMapper.mapStateToArray(state, primary, primaryDot);
943
944
945 final double[][] secondary = new double[additionalEquations.size()][];
946 for (int i = 0; i < additionalEquations.size(); ++i) {
947 final AdditionalEquations additional = additionalEquations.get(i);
948 secondary[i] = state.getAdditionalState(additional.getName());
949 }
950
951 return new ODEStateAndDerivative(stateMapper.mapDateToDouble(state.getDate()),
952 primary, primaryDot,
953 secondary, null);
954
955 }
956
957
958 @Override
959 public boolean isForward() {
960 return mathInterpolator.isForward();
961 }
962
963
964 @Override
965 public AdaptedStepInterpolator restrictStep(final SpacecraftState newPreviousState,
966 final SpacecraftState newCurrentState) {
967 try {
968 final AbstractODEStateInterpolator aosi = (AbstractODEStateInterpolator) mathInterpolator;
969 return new AdaptedStepInterpolator(aosi.restrictStep(convert(newPreviousState),
970 convert(newCurrentState)));
971 } catch (ClassCastException cce) {
972
973 throw new OrekitInternalError(cce);
974 }
975 }
976
977 }
978
979 private class EphemerisModeHandler implements ModeHandler, ODEStepHandler {
980
981
982 private DenseOutputModel model;
983
984
985 private BoundedPropagator ephemeris;
986
987
988 private boolean activate;
989
990
991 private AbsoluteDate endDate;
992
993
994 private final AdaptedStepHandler handler;
995
996
997
998
999 EphemerisModeHandler() {
1000 this.handler = null;
1001 }
1002
1003
1004
1005
1006
1007 EphemerisModeHandler(final OrekitStepHandler handler) {
1008 this.handler = new AdaptedStepHandler(handler);
1009 }
1010
1011
1012 public void initialize(final boolean activateHandlers,
1013 final AbsoluteDate targetDate) {
1014 this.activate = activateHandlers;
1015 this.model = new DenseOutputModel();
1016 this.endDate = targetDate;
1017
1018
1019 this.ephemeris = null;
1020 if (this.handler != null) {
1021 this.handler.initialize(activateHandlers, targetDate);
1022 }
1023 }
1024
1025
1026
1027
1028 public BoundedPropagator getEphemeris() {
1029 return ephemeris;
1030 }
1031
1032
1033 public void handleStep(final ODEStateInterpolator interpolator, final boolean isLast) {
1034 if (activate) {
1035 if (this.handler != null) {
1036 this.handler.handleStep(interpolator, isLast);
1037 }
1038
1039 model.handleStep(interpolator, isLast);
1040 if (isLast) {
1041
1042
1043 final double tI = model.getInitialTime();
1044 final double tF = model.getFinalTime();
1045
1046 final AbsoluteDate startDate =
1047 stateMapper.mapDoubleToDate(tI);
1048 final AbsoluteDate finalDate =
1049 stateMapper.mapDoubleToDate(tF, this.endDate);
1050 final AbsoluteDate minDate;
1051 final AbsoluteDate maxDate;
1052 if (tF < tI) {
1053 minDate = finalDate;
1054 maxDate = startDate;
1055 } else {
1056 minDate = startDate;
1057 maxDate = finalDate;
1058 }
1059
1060
1061 final Map<String, double[]> unmanaged = new HashMap<String, double[]>();
1062 for (final Map.Entry<String, double[]> initial : getInitialState().getAdditionalStates().entrySet()) {
1063 if (!isAdditionalStateManaged(initial.getKey())) {
1064
1065
1066 unmanaged.put(initial.getKey(), initial.getValue());
1067 }
1068 }
1069
1070
1071 final String[] names = new String[additionalEquations.size()];
1072 for (int i = 0; i < names.length; ++i) {
1073 names[i] = additionalEquations.get(i).getName();
1074 }
1075
1076
1077 ephemeris = new IntegratedEphemeris(startDate, minDate, maxDate,
1078 stateMapper, propagationType, model, unmanaged,
1079 getAdditionalStateProviders(), names);
1080
1081 }
1082 }
1083
1084 }
1085
1086
1087 public void init(final ODEStateAndDerivative s0, final double t) {
1088 model.init(s0, t);
1089 if (this.handler != null) {
1090 this.handler.init(s0, t);
1091 }
1092 }
1093
1094 }
1095
1096 }