1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.control.indirect.shooting;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.ode.ODEIntegrator;
22 import org.hipparchus.ode.nonstiff.FieldExplicitRungeKuttaIntegrator;
23 import org.orekit.control.indirect.shooting.propagation.ShootingPropagationSettings;
24 import org.orekit.forces.ForceModel;
25 import org.orekit.forces.gravity.NewtonianAttraction;
26 import org.orekit.orbits.FieldOrbit;
27 import org.orekit.orbits.Orbit;
28 import org.orekit.propagation.FieldSpacecraftState;
29 import org.orekit.propagation.SpacecraftState;
30 import org.orekit.propagation.conversion.FieldExplicitRungeKuttaIntegratorBuilder;
31 import org.orekit.propagation.conversion.ODEIntegratorBuilder;
32 import org.orekit.propagation.integration.AdditionalDerivativesProvider;
33 import org.orekit.propagation.numerical.NumericalPropagator;
34
35
36
37
38
39
40
41 public abstract class AbstractIndirectShooting {
42
43
44 public static final double DEFAULT_TOLERANCE_MASS_ADJOINT = 1e-10;
45
46
47 private final ShootingPropagationSettings propagationSettings;
48
49
50
51
52
53 protected AbstractIndirectShooting(final ShootingPropagationSettings propagationSettings) {
54 this.propagationSettings = propagationSettings;
55 }
56
57
58
59
60
61 public ShootingPropagationSettings getPropagationSettings() {
62 return propagationSettings;
63 }
64
65
66
67
68
69
70
71 public abstract ShootingBoundaryOutput solve(double initialMass, double[] initialGuess);
72
73
74
75
76
77
78 protected NumericalPropagator buildPropagator(final SpacecraftState initialState) {
79 final ODEIntegrator integrator = buildIntegrator(initialState);
80 final NumericalPropagator propagator =
81 new NumericalPropagator(integrator, propagationSettings.getAttitudeProvider());
82 propagator.setIgnoreCentralAttraction(true);
83 propagator.setInitialState(initialState);
84 propagator.setIgnoreCentralAttraction(false);
85 propagator.removeForceModels();
86 if (initialState.isOrbitDefined()) {
87 propagator.setOrbitType(initialState.getOrbit().getType());
88 } else {
89 if (propagationSettings.getForceModels().stream().noneMatch(NewtonianAttraction.class::isInstance)) {
90 propagator.setIgnoreCentralAttraction(true);
91 }
92 propagator.setOrbitType(null);
93 }
94 for (final ForceModel forceModel: propagationSettings.getForceModels()) {
95 propagator.addForceModel(forceModel);
96 }
97 final AdditionalDerivativesProvider derivativesProvider = propagationSettings.getAdjointDynamicsProvider()
98 .buildAdditionalDerivativesProvider();
99 propagator.addAdditionalDerivativesProvider(derivativesProvider);
100 return propagator;
101 }
102
103
104
105
106
107
108 private ODEIntegrator buildIntegrator(final SpacecraftState initialState) {
109 final ODEIntegratorBuilder integratorBuilder = propagationSettings.getIntegrationSettings().getIntegratorBuilder();
110 if (initialState.isOrbitDefined()) {
111 final Orbit orbit = initialState.getOrbit();
112 return integratorBuilder.buildIntegrator(orbit, orbit.getType(), NumericalPropagator.DEFAULT_POSITION_ANGLE_TYPE);
113 } else {
114 return integratorBuilder.buildIntegrator(initialState.getAbsPVA());
115 }
116 }
117
118
119
120
121
122
123
124 protected <T extends CalculusFieldElement<T>> FieldExplicitRungeKuttaIntegrator<T> buildFieldIntegrator(final FieldSpacecraftState<T> initialState) {
125 final Field<T> field = initialState.getMass().getField();
126 final FieldExplicitRungeKuttaIntegratorBuilder<T> integratorBuilder = propagationSettings.getIntegrationSettings()
127 .getFieldIntegratorBuilder(field);
128 if (initialState.isOrbitDefined()) {
129 final FieldOrbit<T> orbit = initialState.getOrbit();
130 return integratorBuilder.buildIntegrator(field, orbit.toOrbit(), orbit.getType(),
131 NumericalPropagator.DEFAULT_POSITION_ANGLE_TYPE);
132 } else {
133 return integratorBuilder.buildIntegrator(initialState.getAbsPVA());
134 }
135 }
136
137 }