1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.conversion.osc2mean;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.List;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.Field;
25 import org.hipparchus.util.MathArrays;
26 import org.orekit.attitudes.Attitude;
27 import org.orekit.attitudes.AttitudeProvider;
28 import org.orekit.attitudes.FieldAttitude;
29 import org.orekit.attitudes.FrameAlignedProvider;
30 import org.orekit.orbits.FieldOrbit;
31 import org.orekit.orbits.Orbit;
32 import org.orekit.orbits.OrbitType;
33 import org.orekit.orbits.PositionAngleType;
34 import org.orekit.propagation.FieldSpacecraftState;
35 import org.orekit.propagation.PropagationType;
36 import org.orekit.propagation.Propagator;
37 import org.orekit.propagation.SpacecraftState;
38 import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
39 import org.orekit.propagation.semianalytical.dsst.forces.FieldShortPeriodTerms;
40 import org.orekit.propagation.semianalytical.dsst.forces.ShortPeriodTerms;
41 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
42 import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
43 import org.orekit.time.FieldAbsoluteDate;
44 import org.orekit.utils.Constants;
45
46
47
48
49
50
51
52 public class DSSTTheory implements MeanTheory {
53
54
55 public static final String THEORY = "DSST";
56
57
58 private final Collection<DSSTForceModel> forceModels;
59
60
61 private final double mass;
62
63
64 private AttitudeProvider attitudeProvider;
65
66
67
68
69
70 public DSSTTheory(final Collection<DSSTForceModel> forceModels) {
71 this(forceModels, null, Propagator.DEFAULT_MASS);
72 }
73
74
75
76
77
78
79
80 public DSSTTheory(final Collection<DSSTForceModel> forceModels,
81 final AttitudeProvider attitudeProvider,
82 final double mass) {
83 this.forceModels = forceModels;
84 this.attitudeProvider = attitudeProvider;
85 this.mass = mass;
86 }
87
88
89 @Override
90 public String getTheoryName() {
91 return THEORY;
92 }
93
94
95 @Override
96 public double getReferenceRadius() {
97 return Constants.IERS2010_EARTH_EQUATORIAL_RADIUS;
98 };
99
100
101 @Override
102 public Orbit preprocessing(final Orbit osculating) {
103
104 if (attitudeProvider == null) {
105
106 attitudeProvider = FrameAlignedProvider.of(osculating.getFrame());
107 }
108
109 for (final DSSTForceModel force : forceModels) {
110 force.registerAttitudeProvider(attitudeProvider);
111 }
112
113 return OrbitType.EQUINOCTIAL.convertType(osculating);
114 }
115
116
117 @Override
118 public Orbit meanToOsculating(final Orbit mean) {
119
120
121 final Attitude attitude = attitudeProvider.getAttitude(mean, mean.getDate(), mean.getFrame());
122 final SpacecraftState meanState = new SpacecraftState(mean, attitude).withMass(mass);
123
124
125 final AuxiliaryElements aux = new AuxiliaryElements(mean, +1);
126
127
128 final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<>();
129 for (final DSSTForceModel force : forceModels) {
130 shortPeriodTerms.addAll(force.initializeShortPeriodTerms(aux, PropagationType.OSCULATING,
131 force.getParameters(mean.getDate())));
132 force.updateShortPeriodTerms(force.getParametersAllValues(), meanState);
133 }
134
135
136 return computeOsculatingOrbit(mean, shortPeriodTerms);
137 }
138
139
140
141
142
143
144
145
146
147 private Orbit computeOsculatingOrbit(final Orbit meanOrbit,
148 final List<ShortPeriodTerms> shortPeriodTerms) {
149
150 final double[] mean = new double[6];
151 final double[] meanDot = new double[6];
152 OrbitType.EQUINOCTIAL.mapOrbitToArray(meanOrbit, PositionAngleType.MEAN, mean, meanDot);
153 final double[] y = mean.clone();
154 for (final ShortPeriodTerms spt : shortPeriodTerms) {
155 final double[] shortPeriodic = spt.value(meanOrbit);
156 for (int i = 0; i < shortPeriodic.length; i++) {
157 y[i] += shortPeriodic[i];
158 }
159 }
160 return OrbitType.EQUINOCTIAL.mapArrayToOrbit(y, meanDot, PositionAngleType.MEAN,
161 meanOrbit.getDate(), meanOrbit.getMu(),
162 meanOrbit.getFrame());
163 }
164
165
166 @Override
167 public <T extends CalculusFieldElement<T>> FieldOrbit<T> preprocessing(final FieldOrbit<T> osculating) {
168
169 if (attitudeProvider == null) {
170
171 attitudeProvider = FrameAlignedProvider.of(osculating.getFrame());
172 }
173
174 for (final DSSTForceModel force : forceModels) {
175 force.registerAttitudeProvider(attitudeProvider);
176 }
177
178 return OrbitType.EQUINOCTIAL.convertType(osculating);
179 }
180
181
182 @Override
183 @SuppressWarnings("unchecked")
184 public <T extends CalculusFieldElement<T>> FieldOrbit<T> meanToOsculating(final FieldOrbit<T> mean) {
185
186 final FieldAbsoluteDate<T> date = mean.getDate();
187 final Field<T> field = date.getField();
188
189
190 final T fieldMass = field.getZero().newInstance(mass);
191 final FieldAttitude<T> attitude = attitudeProvider.getAttitude(mean, mean.getDate(), mean.getFrame());
192 final FieldSpacecraftState<T> meanState = new FieldSpacecraftState<>(mean, attitude).withMass(fieldMass);
193
194
195 final FieldAuxiliaryElements<T> aux = new FieldAuxiliaryElements<>(mean, +1);
196
197
198 final List<FieldShortPeriodTerms<T>> shortPeriodTerms = new ArrayList<>();
199 for (final DSSTForceModel force : forceModels) {
200 shortPeriodTerms.addAll(force.initializeShortPeriodTerms(aux, PropagationType.OSCULATING,
201 force.getParameters(field, date)));
202 force.updateShortPeriodTerms(force.getParametersAllValues(field), meanState);
203 }
204
205
206 return computeOsculatingOrbit(mean, shortPeriodTerms);
207 }
208
209
210
211
212
213
214
215
216
217
218 private <T extends CalculusFieldElement<T>> FieldOrbit<T> computeOsculatingOrbit(final FieldOrbit<T> meanOrbit,
219 final List<FieldShortPeriodTerms<T>> shortPeriodTerms) {
220
221 final T[] mean = MathArrays.buildArray(meanOrbit.getDate().getField(), 6);
222 final T[] meanDot = MathArrays.buildArray(meanOrbit.getDate().getField(), 6);
223 OrbitType.EQUINOCTIAL.mapOrbitToArray(meanOrbit, PositionAngleType.MEAN, mean, meanDot);
224 final T[] y = mean.clone();
225 for (final FieldShortPeriodTerms<T> spt : shortPeriodTerms) {
226 final T[] shortPeriodic = spt.value(meanOrbit);
227 for (int i = 0; i < shortPeriodic.length; i++) {
228 y[i] = y[i].add(shortPeriodic[i]);
229 }
230 }
231 return OrbitType.EQUINOCTIAL.mapArrayToOrbit(y, meanDot,
232 PositionAngleType.MEAN,
233 meanOrbit.getDate(),
234 meanOrbit.getMu(),
235 meanOrbit.getFrame());
236 }
237 }