1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.hipparchus.ode.ODEIntegrator;
30 import org.hipparchus.ode.ODEStateAndDerivative;
31 import org.hipparchus.ode.sampling.ODEStateInterpolator;
32 import org.hipparchus.ode.sampling.ODEStepHandler;
33 import org.hipparchus.util.FastMath;
34 import org.hipparchus.util.MathUtils;
35 import org.orekit.annotation.DefaultDataContext;
36 import org.orekit.attitudes.Attitude;
37 import org.orekit.attitudes.AttitudeProvider;
38 import org.orekit.data.DataContext;
39 import org.orekit.errors.OrekitException;
40 import org.orekit.errors.OrekitInternalError;
41 import org.orekit.errors.OrekitMessages;
42 import org.orekit.frames.Frame;
43 import org.orekit.orbits.EquinoctialOrbit;
44 import org.orekit.orbits.Orbit;
45 import org.orekit.orbits.OrbitType;
46 import org.orekit.orbits.PositionAngle;
47 import org.orekit.propagation.PropagationType;
48 import org.orekit.propagation.Propagator;
49 import org.orekit.propagation.SpacecraftState;
50 import org.orekit.propagation.events.EventDetector;
51 import org.orekit.propagation.integration.AbstractIntegratedPropagator;
52 import org.orekit.propagation.integration.StateMapper;
53 import org.orekit.propagation.numerical.NumericalPropagator;
54 import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
55 import org.orekit.propagation.semianalytical.dsst.forces.DSSTNewtonianAttraction;
56 import org.orekit.propagation.semianalytical.dsst.forces.ShortPeriodTerms;
57 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
58 import org.orekit.propagation.semianalytical.dsst.utilities.FixedNumberInterpolationGrid;
59 import org.orekit.propagation.semianalytical.dsst.utilities.InterpolationGrid;
60 import org.orekit.propagation.semianalytical.dsst.utilities.MaxGapInterpolationGrid;
61 import org.orekit.time.AbsoluteDate;
62 import org.orekit.utils.ParameterDriver;
63 import org.orekit.utils.ParameterObserver;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public class DSSTPropagator extends AbstractIntegratedPropagator {
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 private static final int I = 1;
141
142
143 private static final double EPSILON_DEFAULT = 1.0e-13;
144
145
146 private static final int MAX_ITERATIONS_DEFAULT = 200;
147
148
149 private static final int INTERPOLATION_POINTS_PER_STEP = 3;
150
151
152 private boolean initialIsOsculating;
153
154
155 private final transient List<DSSTForceModel> forceModels;
156
157
158 private MeanPlusShortPeriodicMapper mapper;
159
160
161 private InterpolationGrid interpolationgrid;
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 @DefaultDataContext
178 public DSSTPropagator(final ODEIntegrator integrator, final PropagationType propagationType) {
179 this(integrator, propagationType,
180 Propagator.getDefaultLaw(DataContext.getDefault().getFrames()));
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195 public DSSTPropagator(final ODEIntegrator integrator,
196 final PropagationType propagationType,
197 final AttitudeProvider attitudeProvider) {
198 super(integrator, propagationType);
199 forceModels = new ArrayList<DSSTForceModel>();
200 initMapper();
201
202 setOrbitType(OrbitType.EQUINOCTIAL);
203 setPositionAngleType(PositionAngle.MEAN);
204 setAttitudeProvider(attitudeProvider);
205 setInterpolationGridToFixedNumberOfPoints(INTERPOLATION_POINTS_PER_STEP);
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 @DefaultDataContext
224 public DSSTPropagator(final ODEIntegrator integrator) {
225 this(integrator, PropagationType.MEAN);
226 }
227
228
229
230
231
232
233
234
235
236
237
238 public void setMu(final double mu) {
239 addForceModel(new DSSTNewtonianAttraction(mu));
240 }
241
242
243
244
245 private void superSetMu(final double mu) {
246 super.setMu(mu);
247 }
248
249
250
251
252
253
254
255 private boolean hasNewtonianAttraction() {
256 final int last = forceModels.size() - 1;
257 return last >= 0 && forceModels.get(last) instanceof DSSTNewtonianAttraction;
258 }
259
260
261
262
263 public void setInitialState(final SpacecraftState initialState) {
264 setInitialState(initialState, PropagationType.OSCULATING);
265 }
266
267
268
269
270
271 public void setInitialState(final SpacecraftState initialState,
272 final PropagationType stateType) {
273 switch (stateType) {
274 case MEAN:
275 initialIsOsculating = false;
276 break;
277 case OSCULATING:
278 initialIsOsculating = true;
279 break;
280 default:
281 throw new OrekitInternalError(null);
282 }
283 resetInitialState(initialState);
284 }
285
286
287
288
289
290 @Override
291 public void resetInitialState(final SpacecraftState state) {
292 super.resetInitialState(state);
293 if (!hasNewtonianAttraction()) {
294
295 setMu(state.getMu());
296 }
297 super.setStartDate(state.getDate());
298 }
299
300
301
302
303
304 public void setSelectedCoefficients(final Set<String> selectedCoefficients) {
305 mapper.setSelectedCoefficients(selectedCoefficients == null ?
306 null : new HashSet<String>(selectedCoefficients));
307 }
308
309
310
311
312
313 public Set<String> getSelectedCoefficients() {
314 final Set<String> set = mapper.getSelectedCoefficients();
315 return set == null ? null : Collections.unmodifiableSet(set);
316 }
317
318
319
320
321 public boolean initialIsOsculating() {
322 return initialIsOsculating;
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 public void setInterpolationGridToFixedNumberOfPoints(final int interpolationPoints) {
341 interpolationgrid = new FixedNumberInterpolationGrid(interpolationPoints);
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358 public void setInterpolationGridToMaxTimeGap(final double maxGap) {
359 interpolationgrid = new MaxGapInterpolationGrid(maxGap);
360 }
361
362
363
364
365
366
367
368
369
370
371 public void addForceModel(final DSSTForceModel force) {
372
373 if (force instanceof DSSTNewtonianAttraction) {
374
375
376
377 force.getParametersDrivers()[0].addObserver(new ParameterObserver() {
378
379 @Override
380 public void valueChanged(final double previousValue, final ParameterDriver driver) {
381 superSetMu(driver.getValue());
382 }
383 });
384
385 if (hasNewtonianAttraction()) {
386
387 forceModels.set(forceModels.size() - 1, force);
388 } else {
389
390 forceModels.add(force);
391 }
392 } else {
393
394 if (hasNewtonianAttraction()) {
395
396
397 forceModels.add(forceModels.size() - 1, force);
398 } else {
399
400 forceModels.add(force);
401 }
402 }
403
404 force.registerAttitudeProvider(getAttitudeProvider());
405
406 }
407
408
409
410
411
412
413
414
415
416 public void removeForceModels() {
417 final int last = forceModels.size() - 1;
418 if (hasNewtonianAttraction()) {
419
420 final DSSTForceModel newton = forceModels.get(last);
421 forceModels.clear();
422 forceModels.add(newton);
423 } else {
424 forceModels.clear();
425 }
426 }
427
428
429
430
431
432
433
434 public List<DSSTForceModel> getAllForceModels() {
435 return Collections.unmodifiableList(forceModels);
436 }
437
438
439
440
441 public OrbitType getOrbitType() {
442 return super.getOrbitType();
443 }
444
445
446
447
448 public PositionAngle getPositionAngleType() {
449 return super.getPositionAngleType();
450 }
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468 public static SpacecraftStateraftState">SpacecraftState computeOsculatingState(final SpacecraftState mean,
469 final AttitudeProvider attitudeProvider,
470 final Collection<DSSTForceModel> forces) {
471
472
473 final AuxiliaryElementsical/dsst/utilities/AuxiliaryElements.html#AuxiliaryElements">AuxiliaryElements aux = new AuxiliaryElements(mean.getOrbit(), I);
474
475
476 final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<ShortPeriodTerms>();
477 for (final DSSTForceModel force : forces) {
478 force.registerAttitudeProvider(attitudeProvider);
479 shortPeriodTerms.addAll(force.initialize(aux, PropagationType.OSCULATING, force.getParameters()));
480 force.updateShortPeriodTerms(force.getParameters(), mean);
481 }
482
483 final EquinoctialOrbit osculatingOrbit = computeOsculatingOrbit(mean, shortPeriodTerms);
484
485 return new SpacecraftState(osculatingOrbit, mean.getAttitude(), mean.getMass(),
486 mean.getAdditionalStates());
487
488 }
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508 public static SpacecraftStateSpacecraftState">SpacecraftState computeMeanState(final SpacecraftState osculating,
509 final AttitudeProvider attitudeProvider,
510 final Collection<DSSTForceModel> forceModels) {
511 return computeMeanState(osculating, attitudeProvider, forceModels, EPSILON_DEFAULT, MAX_ITERATIONS_DEFAULT);
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 public static SpacecraftStateSpacecraftState">SpacecraftState computeMeanState(final SpacecraftState osculating,
536 final AttitudeProvider attitudeProvider,
537 final Collection<DSSTForceModel> forceModels,
538 final double epsilon,
539 final int maxIterations) {
540 final Orbit meanOrbit = computeMeanOrbit(osculating, attitudeProvider, forceModels, epsilon, maxIterations);
541 return new SpacecraftState(meanOrbit, osculating.getAttitude(), osculating.getMass(), osculating.getAdditionalStates());
542 }
543
544
545
546
547
548
549
550
551
552
553 public void setSatelliteRevolution(final int satelliteRevolution) {
554 mapper.setSatelliteRevolution(satelliteRevolution);
555 }
556
557
558
559
560 public int getSatelliteRevolution() {
561 return mapper.getSatelliteRevolution();
562 }
563
564
565 @Override
566 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
567 super.setAttitudeProvider(attitudeProvider);
568
569
570 for (final DSSTForceModel force : forceModels) {
571 force.registerAttitudeProvider(attitudeProvider);
572 }
573 }
574
575
576
577
578
579
580
581
582 @Override
583 protected void beforeIntegration(final SpacecraftState initialState,
584 final AbsoluteDate tEnd) {
585
586
587 final PropagationType type = isMeanOrbit();
588
589
590 final AuxiliaryElementsical/dsst/utilities/AuxiliaryElements.html#AuxiliaryElements">AuxiliaryElements aux = new AuxiliaryElements(initialState.getOrbit(), I);
591
592
593 final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<ShortPeriodTerms>();
594 for (final DSSTForceModel force : forceModels) {
595 shortPeriodTerms.addAll(force.initialize(aux, type, force.getParameters()));
596 }
597 mapper.setShortPeriodTerms(shortPeriodTerms);
598
599
600 if (type == PropagationType.OSCULATING) {
601 final ShortPeriodicsHandler spHandler = new ShortPeriodicsHandler(forceModels);
602
603 for (DSSTForceModel forceModel : forceModels) {
604 forceModel.updateShortPeriodTerms(forceModel.getParameters(), initialState);
605 }
606 final Collection<ODEStepHandler> stepHandlers = new ArrayList<ODEStepHandler>();
607 stepHandlers.add(spHandler);
608 final ODEIntegrator integrator = getIntegrator();
609 final Collection<ODEStepHandler> existing = integrator.getStepHandlers();
610 stepHandlers.addAll(existing);
611
612 integrator.clearStepHandlers();
613
614
615 for (final ODEStepHandler sp : stepHandlers) {
616 integrator.addStepHandler(sp);
617 }
618 }
619 }
620
621
622 @Override
623 protected void afterIntegration() {
624
625 if (isMeanOrbit() == PropagationType.OSCULATING) {
626 final List<ODEStepHandler> preserved = new ArrayList<ODEStepHandler>();
627 final ODEIntegrator integrator = getIntegrator();
628 for (final ODEStepHandler sp : integrator.getStepHandlers()) {
629 if (!(sp instanceof ShortPeriodicsHandler)) {
630 preserved.add(sp);
631 }
632 }
633
634
635 integrator.clearStepHandlers();
636
637
638 for (final ODEStepHandler sp : preserved) {
639 integrator.addStepHandler(sp);
640 }
641 }
642 }
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658 private static Orbit computeMeanOrbit(final SpacecraftState osculating,
659 final AttitudeProvider attitudeProvider,
660 final Collection<DSSTForceModel> forceModels, final double epsilon, final int maxIterations) {
661
662
663 EquinoctialOrbit./org/orekit/orbits/EquinoctialOrbit.html#EquinoctialOrbit">EquinoctialOrbit meanOrbit = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(osculating.getOrbit());
664
665
666 final double thresholdA = epsilon * (1 + FastMath.abs(meanOrbit.getA()));
667 final double thresholdE = epsilon * (1 + meanOrbit.getE());
668 final double thresholdI = epsilon * (1 + meanOrbit.getI());
669 final double thresholdL = epsilon * FastMath.PI;
670
671
672 for (final DSSTForceModel force : forceModels) {
673 force.registerAttitudeProvider(attitudeProvider);
674 }
675
676 int i = 0;
677 while (i++ < maxIterations) {
678
679 final SpacecraftStatee.html#SpacecraftState">SpacecraftState meanState = new SpacecraftState(meanOrbit, osculating.getAttitude(), osculating.getMass());
680
681
682 final AuxiliaryElementsical/dsst/utilities/AuxiliaryElements.html#AuxiliaryElements">AuxiliaryElements aux = new AuxiliaryElements(meanOrbit, I);
683
684
685 final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<ShortPeriodTerms>();
686 for (final DSSTForceModel force : forceModels) {
687 shortPeriodTerms.addAll(force.initialize(aux, PropagationType.OSCULATING, force.getParameters()));
688 force.updateShortPeriodTerms(force.getParameters(), meanState);
689 }
690
691
692 final EquinoctialOrbit rebuilt = computeOsculatingOrbit(meanState, shortPeriodTerms);
693
694
695 final double deltaA = osculating.getA() - rebuilt.getA();
696 final double deltaEx = osculating.getEquinoctialEx() - rebuilt.getEquinoctialEx();
697 final double deltaEy = osculating.getEquinoctialEy() - rebuilt.getEquinoctialEy();
698 final double deltaHx = osculating.getHx() - rebuilt.getHx();
699 final double deltaHy = osculating.getHy() - rebuilt.getHy();
700 final double deltaLv = MathUtils.normalizeAngle(osculating.getLv() - rebuilt.getLv(), 0.0);
701
702
703 if (FastMath.abs(deltaA) < thresholdA &&
704 FastMath.abs(deltaEx) < thresholdE &&
705 FastMath.abs(deltaEy) < thresholdE &&
706 FastMath.abs(deltaHx) < thresholdI &&
707 FastMath.abs(deltaHy) < thresholdI &&
708 FastMath.abs(deltaLv) < thresholdL) {
709 return meanOrbit;
710 }
711
712
713 meanOrbit = new EquinoctialOrbit(meanOrbit.getA() + deltaA,
714 meanOrbit.getEquinoctialEx() + deltaEx,
715 meanOrbit.getEquinoctialEy() + deltaEy,
716 meanOrbit.getHx() + deltaHx,
717 meanOrbit.getHy() + deltaHy,
718 meanOrbit.getLv() + deltaLv,
719 PositionAngle.TRUE, meanOrbit.getFrame(),
720 meanOrbit.getDate(), meanOrbit.getMu());
721 }
722
723 throw new OrekitException(OrekitMessages.UNABLE_TO_COMPUTE_DSST_MEAN_PARAMETERS, i);
724
725 }
726
727
728
729
730
731
732
733
734
735 private static EquinoctialOrbit computeOsculatingOrbit(final SpacecraftState meanState,
736 final List<ShortPeriodTerms> shortPeriodTerms) {
737
738 final double[] mean = new double[6];
739 final double[] meanDot = new double[6];
740 OrbitType.EQUINOCTIAL.mapOrbitToArray(meanState.getOrbit(), PositionAngle.MEAN, mean, meanDot);
741 final double[] y = mean.clone();
742 for (final ShortPeriodTerms spt : shortPeriodTerms) {
743 final double[] shortPeriodic = spt.value(meanState.getOrbit());
744 for (int i = 0; i < shortPeriodic.length; i++) {
745 y[i] += shortPeriodic[i];
746 }
747 }
748 return (EquinoctialOrbit) OrbitType.EQUINOCTIAL.mapArrayToOrbit(y, meanDot,
749 PositionAngle.MEAN, meanState.getDate(),
750 meanState.getMu(), meanState.getFrame());
751 }
752
753
754 @Override
755 protected SpacecraftState getInitialIntegrationState() {
756 if (initialIsOsculating) {
757
758
759 return computeMeanState(getInitialState(), getAttitudeProvider(), forceModels);
760 } else {
761
762 return getInitialState();
763 }
764 }
765
766
767
768
769
770
771
772
773 @Override
774 protected StateMapper createMapper(final AbsoluteDate referenceDate, final double mu,
775 final OrbitType ignoredOrbitType, final PositionAngle ignoredPositionAngleType,
776 final AttitudeProvider attitudeProvider, final Frame frame) {
777
778
779 final MeanPlusShortPeriodicMapper newMapper =
780 new MeanPlusShortPeriodicMapper(referenceDate, mu, attitudeProvider, frame);
781
782
783 if (mapper != null) {
784 newMapper.setSatelliteRevolution(mapper.getSatelliteRevolution());
785 newMapper.setSelectedCoefficients(mapper.getSelectedCoefficients());
786 newMapper.setShortPeriodTerms(mapper.getShortPeriodTerms());
787 }
788
789 mapper = newMapper;
790 return mapper;
791
792 }
793
794
795 private static class MeanPlusShortPeriodicMapper extends StateMapper {
796
797
798 private Set<String> selectedCoefficients;
799
800
801 private int satelliteRevolution;
802
803
804 private List<ShortPeriodTerms> shortPeriodTerms;
805
806
807
808
809
810
811
812 MeanPlusShortPeriodicMapper(final AbsoluteDate referenceDate, final double mu,
813 final AttitudeProvider attitudeProvider, final Frame frame) {
814
815 super(referenceDate, mu, OrbitType.EQUINOCTIAL, PositionAngle.MEAN, attitudeProvider, frame);
816
817 this.selectedCoefficients = null;
818
819
820 this.satelliteRevolution = 2;
821
822 this.shortPeriodTerms = Collections.emptyList();
823
824 }
825
826
827 @Override
828 public SpacecraftState mapArrayToState(final AbsoluteDate date,
829 final double[] y, final double[] yDot,
830 final PropagationType type) {
831
832
833
834
835 final double[] elements = y.clone();
836 final Map<String, double[]> coefficients;
837 switch (type) {
838 case MEAN:
839 coefficients = null;
840 break;
841 case OSCULATING:
842 final Orbit meanOrbit = OrbitType.EQUINOCTIAL.mapArrayToOrbit(elements, yDot, PositionAngle.MEAN, date, getMu(), getFrame());
843 coefficients = selectedCoefficients == null ? null : new HashMap<String, double[]>();
844 for (final ShortPeriodTerms spt : shortPeriodTerms) {
845 final double[] shortPeriodic = spt.value(meanOrbit);
846 for (int i = 0; i < shortPeriodic.length; i++) {
847 elements[i] += shortPeriodic[i];
848 }
849 if (selectedCoefficients != null) {
850 coefficients.putAll(spt.getCoefficients(date, selectedCoefficients));
851 }
852 }
853 break;
854 default:
855 throw new OrekitInternalError(null);
856 }
857
858 final double mass = elements[6];
859 if (mass <= 0.0) {
860 throw new OrekitException(OrekitMessages.SPACECRAFT_MASS_BECOMES_NEGATIVE, mass);
861 }
862
863 final Orbit orbit = OrbitType.EQUINOCTIAL.mapArrayToOrbit(elements, yDot, PositionAngle.MEAN, date, getMu(), getFrame());
864 final Attitude attitude = getAttitudeProvider().getAttitude(orbit, date, getFrame());
865
866 if (coefficients == null) {
867 return new SpacecraftState(orbit, attitude, mass);
868 } else {
869 return new SpacecraftState(orbit, attitude, mass, coefficients);
870 }
871
872 }
873
874
875 @Override
876 public void mapStateToArray(final SpacecraftState state, final double[] y, final double[] yDot) {
877
878 OrbitType.EQUINOCTIAL.mapOrbitToArray(state.getOrbit(), PositionAngle.MEAN, y, yDot);
879 y[6] = state.getMass();
880
881 }
882
883
884
885
886
887
888
889
890
891
892 public void setSatelliteRevolution(final int satelliteRevolution) {
893 this.satelliteRevolution = satelliteRevolution;
894 }
895
896
897
898
899 public int getSatelliteRevolution() {
900 return satelliteRevolution;
901 }
902
903
904
905
906
907 public void setSelectedCoefficients(final Set<String> selectedCoefficients) {
908 this.selectedCoefficients = selectedCoefficients;
909 }
910
911
912
913
914
915 public Set<String> getSelectedCoefficients() {
916 return selectedCoefficients;
917 }
918
919
920
921
922
923 public void setShortPeriodTerms(final List<ShortPeriodTerms> shortPeriodTerms) {
924 this.shortPeriodTerms = shortPeriodTerms;
925 }
926
927
928
929
930
931 public List<ShortPeriodTerms> getShortPeriodTerms() {
932 return shortPeriodTerms;
933 }
934
935 }
936
937
938 @Override
939 protected MainStateEquations getMainStateEquations(final ODEIntegrator integrator) {
940 return new Main(integrator);
941 }
942
943
944 private class Main implements MainStateEquations {
945
946
947 private final double[] yDot;
948
949
950
951
952 Main(final ODEIntegrator integrator) {
953 yDot = new double[7];
954
955 for (final DSSTForceModel forceModel : forceModels) {
956 final EventDetector[] modelDetectors = forceModel.getEventsDetectors();
957 if (modelDetectors != null) {
958 for (final EventDetector detector : modelDetectors) {
959 setUpEventDetector(integrator, detector);
960 }
961 }
962 }
963
964 }
965
966
967 @Override
968 public double[] computeDerivatives(final SpacecraftState state) {
969
970 Arrays.fill(yDot, 0.0);
971
972
973 final AuxiliaryElementsities/AuxiliaryElements.html#AuxiliaryElements">AuxiliaryElements auxiliaryElements = new AuxiliaryElements(state.getOrbit(), I);
974
975
976 for (final DSSTForceModel forceModel : forceModels) {
977 final double[] daidt = elementRates(forceModel, state, auxiliaryElements, forceModel.getParameters());
978 for (int i = 0; i < daidt.length; i++) {
979 yDot[i] += daidt[i];
980 }
981 }
982
983 return yDot.clone();
984 }
985
986
987
988
989
990
991
992
993
994 private double[] elementRates(final DSSTForceModel forceModel,
995 final SpacecraftState state,
996 final AuxiliaryElements auxiliaryElements,
997 final double[] parameters) {
998 return forceModel.getMeanElementRate(state, auxiliaryElements, parameters);
999 }
1000
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029 public static double[][] tolerances(final double dP, final Orbit orbit) {
1030
1031 return NumericalPropagator.tolerances(dP, orbit, OrbitType.EQUINOCTIAL);
1032
1033 }
1034
1035
1036
1037
1038 private class ShortPeriodicsHandler implements ODEStepHandler {
1039
1040
1041 private final List<DSSTForceModel> forceModels;
1042
1043
1044
1045
1046 ShortPeriodicsHandler(final List<DSSTForceModel> forceModels) {
1047 this.forceModels = forceModels;
1048 }
1049
1050
1051 @Override
1052 public void handleStep(final ODEStateInterpolator interpolator, final boolean isLast) {
1053
1054
1055 final double[] interpolationPoints =
1056 interpolationgrid.getGridPoints(interpolator.getPreviousState().getTime(),
1057 interpolator.getCurrentState().getTime());
1058
1059 final SpacecraftStatetml#SpacecraftState">SpacecraftState[] meanStates = new SpacecraftState[interpolationPoints.length];
1060 for (int i = 0; i < interpolationPoints.length; ++i) {
1061
1062
1063 final double time = interpolationPoints[i];
1064 final ODEStateAndDerivative sd = interpolator.getInterpolatedState(time);
1065 meanStates[i] = mapper.mapArrayToState(time,
1066 sd.getPrimaryState(),
1067 sd.getPrimaryDerivative(),
1068 PropagationType.MEAN);
1069 }
1070
1071
1072 for (DSSTForceModel forceModel : forceModels) {
1073 forceModel.updateShortPeriodTerms(forceModel.getParameters(), meanStates);
1074 }
1075
1076 }
1077 }
1078 }