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.Collection;
20 import java.util.NavigableMap;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
24 import org.hipparchus.geometry.euclidean.threed.Rotation;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.orekit.attitudes.Attitude;
27 import org.orekit.attitudes.AttitudeProvider;
28 import org.orekit.attitudes.FieldAttitude;
29 import org.orekit.errors.OrekitException;
30 import org.orekit.errors.OrekitMessages;
31 import org.orekit.frames.Frame;
32 import org.orekit.orbits.Orbit;
33 import org.orekit.propagation.BoundedPropagator;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.time.AbsoluteDate;
36 import org.orekit.time.FieldAbsoluteDate;
37 import org.orekit.utils.FieldPVCoordinatesProvider;
38 import org.orekit.utils.PVCoordinatesProvider;
39 import org.orekit.utils.TimeSpanMap;
40 import org.orekit.utils.TimeSpanMap.Span;
41 import org.orekit.utils.TimeStampedPVCoordinates;
42
43
44
45
46
47
48
49
50
51 public class AggregateBoundedPropagator extends AbstractAnalyticalPropagator
52 implements BoundedPropagator {
53
54
55 private final TimeSpanMap<BoundedPropagator> map;
56
57
58 private final AbsoluteDate min;
59
60
61 private final AbsoluteDate max;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public AggregateBoundedPropagator(final Collection<? extends BoundedPropagator> propagators) {
78 super(null);
79 map = new TimeSpanMap<>(null);
80 propagators.forEach(p -> map.addValidAfter(p, p.getMinDate(), false));
81 setAttitudeProvider();
82 this.min = map.getFirstNonNullSpan().getData().getMinDate();
83 this.max = map.getLastNonNullSpan().getData().getMaxDate();
84 super.resetInitialState(getInitialState());
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98 public AggregateBoundedPropagator(final NavigableMap<AbsoluteDate, ? extends BoundedPropagator> propagators,
99 final AbsoluteDate min, final AbsoluteDate max) {
100 super(null);
101 map = new TimeSpanMap<>(null);
102 propagators.forEach((d, p) -> map.addValidAfter(p, p.getMinDate(), false));
103 setAttitudeProvider();
104 this.min = min;
105 this.max = max;
106 super.resetInitialState(getInitialState());
107 }
108
109
110
111
112
113
114
115
116 private void setAttitudeProvider() {
117
118
119 boolean nullFound = false;
120 boolean nonNullFound = false;
121 for (Span<BoundedPropagator> span = map.getFirstSpan(); span != null; span = span.next()) {
122 if (span.getData() != null) {
123 final AttitudeProvider attitudeProvider = span.getData().getAttitudeProvider();
124 nullFound |= attitudeProvider == null;
125 nonNullFound |= attitudeProvider != null;
126 }
127 }
128
129
130 if (nullFound ) {
131 if (nonNullFound) {
132 throw new OrekitException(OrekitMessages.BOTH_NULL_AND_NON_NULL_ATTITUDE_PROVIDERS);
133 } else {
134
135 setAttitudeProvider(null);
136 }
137 } else {
138 if (nonNullFound) {
139
140 setAttitudeProvider(new AggregateAttitudeProvider());
141 } else {
142
143 throw new OrekitException(OrekitMessages.NOT_ENOUGH_PROPAGATORS);
144 }
145 }
146
147 }
148
149
150
151
152
153 public TimeSpanMap<BoundedPropagator> getPropagatorsMap() {
154 return map;
155 }
156
157 @Override
158 public SpacecraftState basicPropagate(final AbsoluteDate date) {
159
160
161
162
163 final SpacecraftState state = getPropagator(date).propagate(date);
164
165 if (getAttitudeProvider() == null ||
166 getAttitudeProvider() instanceof AggregateAttitudeProvider) {
167
168
169 return state;
170 } else {
171
172
173
174 final Attitude attitude =
175 getAttitudeProvider().getAttitude(this, date, state.getFrame());
176
177
178 if (state.isOrbitDefined()) {
179 return new SpacecraftState(state.getOrbit(), attitude, state.getMass(),
180 state.getAdditionalDataValues(), state.getAdditionalStatesDerivatives());
181 } else {
182 return new SpacecraftState(state.getAbsPVA(), attitude, state.getMass(),
183 state.getAdditionalDataValues(), state.getAdditionalStatesDerivatives());
184 }
185 }
186 }
187
188 @Override
189 public TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame frame) {
190 return getPropagator(date).getPVCoordinates(date, frame);
191 }
192
193 @Override
194 public Vector3D getPosition(final AbsoluteDate date, final Frame frame) {
195 return getPropagator(date).propagate(date).getPosition(frame);
196 }
197
198 @Override
199 public Orbit propagateOrbit(final AbsoluteDate date) {
200 return getPropagator(date).propagate(date).getOrbit();
201 }
202
203 @Override
204 public AbsoluteDate getMinDate() {
205 return min;
206 }
207
208 @Override
209 public AbsoluteDate getMaxDate() {
210 return max;
211 }
212
213 @Override
214 protected double getMass(final AbsoluteDate date) {
215 return getPropagator(date).propagate(date).getMass();
216 }
217
218 @Override
219 public SpacecraftState getInitialState() {
220 return map.getFirstNonNullSpan().getData().getInitialState();
221 }
222
223 @Override
224 protected void resetIntermediateState(final SpacecraftState state, final boolean forward) {
225 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
226 }
227
228 @Override
229 public void resetInitialState(final SpacecraftState state) {
230 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
231 }
232
233
234
235
236
237
238
239 private BoundedPropagator getPropagator(final AbsoluteDate date) {
240 final BoundedPropagator propagator = map.get(date);
241 if (propagator != null) {
242 return propagator;
243 } else {
244
245 return map.getFirstNonNullSpan().getData();
246 }
247 }
248
249
250 private class AggregateAttitudeProvider implements AttitudeProvider {
251
252
253 @Override
254 public Attitude getAttitude(final PVCoordinatesProvider pvProv,
255 final AbsoluteDate date,
256 final Frame frame) {
257 return getPropagator(date).getAttitudeProvider().getAttitude(pvProv, date, frame);
258 }
259
260
261 @Override
262 public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
263 final FieldAbsoluteDate<T> date,
264 final Frame frame) {
265 return getPropagator(date.toAbsoluteDate()).getAttitudeProvider().getAttitude(pvProv, date, frame);
266 }
267
268
269 @Override
270 public Rotation getAttitudeRotation(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) {
271 return getPropagator(date).getAttitudeProvider().getAttitudeRotation(pvProv, date, frame);
272 }
273
274
275 @Override
276 public <T extends CalculusFieldElement<T>> FieldRotation<T> getAttitudeRotation(final FieldPVCoordinatesProvider<T> pvProv,
277 final FieldAbsoluteDate<T> date,
278 final Frame frame) {
279 return getPropagator(date.toAbsoluteDate()).getAttitudeProvider().getAttitudeRotation(pvProv, date, frame);
280 }
281 }
282
283 }