1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.hipparchus.CalculusFieldElement;
26 import org.hipparchus.Field;
27 import org.orekit.attitudes.AttitudeProvider;
28 import org.orekit.errors.OrekitException;
29 import org.orekit.errors.OrekitMessages;
30 import org.orekit.frames.Frame;
31 import org.orekit.propagation.sampling.FieldStepHandlerMultiplexer;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.FieldAbsoluteDate;
34 import org.orekit.utils.TimeSpanMap;
35 import org.orekit.utils.TimeStampedFieldPVCoordinates;
36
37
38
39
40
41
42
43
44
45
46 public abstract class FieldAbstractPropagator<T extends CalculusFieldElement<T>> implements FieldPropagator<T> {
47
48
49 private FieldStepHandlerMultiplexer<T> multiplexer;
50
51
52 private FieldAbsoluteDate<T> startDate;
53
54
55 private AttitudeProvider attitudeProvider;
56
57
58 private final List<FieldAdditionalStateProvider<T>> additionalStateProviders;
59
60
61 private final Map<String, TimeSpanMap<T[]>> unmanagedStates;
62
63
64 private final Field<T> field;
65
66
67 private FieldSpacecraftState<T> initialState;
68
69
70
71
72 protected FieldAbstractPropagator(final Field<T> field) {
73 this.field = field;
74 multiplexer = new FieldStepHandlerMultiplexer<>();
75 additionalStateProviders = new ArrayList<>();
76 unmanagedStates = new HashMap<>();
77 }
78
79
80
81
82 protected void setStartDate(final FieldAbsoluteDate<T> startDate) {
83 this.startDate = startDate;
84 }
85
86
87
88
89 protected FieldAbsoluteDate<T> getStartDate() {
90 return startDate;
91 }
92
93
94 public AttitudeProvider getAttitudeProvider() {
95 return attitudeProvider;
96 }
97
98
99 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
100 this.attitudeProvider = attitudeProvider;
101 }
102
103
104
105 public Field<T> getField() {
106 return field;
107 }
108
109
110 public FieldSpacecraftState<T> getInitialState() {
111 return initialState;
112 }
113
114
115 public Frame getFrame() {
116 return initialState.getFrame();
117 }
118
119
120 public void resetInitialState(final FieldSpacecraftState<T> state) {
121 initialState = state;
122 setStartDate(state.getDate());
123 }
124
125
126 public FieldStepHandlerMultiplexer<T> getMultiplexer() {
127 return multiplexer;
128 }
129
130
131 public void addAdditionalStateProvider(final FieldAdditionalStateProvider<T> additionalStateProvider) {
132
133
134 if (isAdditionalStateManaged(additionalStateProvider.getName())) {
135
136 throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
137 additionalStateProvider.getName());
138 }
139
140
141 additionalStateProviders.add(additionalStateProvider);
142
143 }
144
145
146 public List<FieldAdditionalStateProvider<T>> getAdditionalStateProviders() {
147 return Collections.unmodifiableList(additionalStateProviders);
148 }
149
150
151
152
153
154
155 protected FieldSpacecraftState<T> updateAdditionalStates(final FieldSpacecraftState<T> original) {
156
157
158
159 FieldSpacecraftState<T> updated = original;
160
161
162 for (final Map.Entry<String, TimeSpanMap<T[]>> entry : unmanagedStates.entrySet()) {
163 updated = updated.addAdditionalState(entry.getKey(),
164 entry.getValue().get(original.getDate().toAbsoluteDate()));
165 }
166
167
168 for (final FieldAdditionalStateProvider<T> provider : additionalStateProviders) {
169
170 updated = updated.addAdditionalState(provider.getName(),
171 provider.getAdditionalState(updated));
172 }
173
174 return updated;
175
176 }
177
178
179 public boolean isAdditionalStateManaged(final String name) {
180 for (final FieldAdditionalStateProvider<T> provider : additionalStateProviders) {
181 if (provider.getName().equals(name)) {
182 return true;
183 }
184 }
185 return false;
186 }
187
188
189 public String[] getManagedAdditionalStates() {
190 final String[] managed = new String[additionalStateProviders.size()];
191 for (int i = 0; i < managed.length; ++i) {
192 managed[i] = additionalStateProviders.get(i).getName();
193 }
194 return managed;
195 }
196
197
198 public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> target) {
199 if (startDate == null) {
200 startDate = getInitialState().getDate();
201 }
202 return propagate(startDate, target);
203 }
204
205
206 public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date, final Frame frame) {
207 return propagate(date).getPVCoordinates(frame);
208 }
209
210
211
212
213 protected void initializePropagation() {
214
215 unmanagedStates.clear();
216
217 if (initialState != null) {
218
219
220
221 for (final Map.Entry<String, T[]> initial : initialState.getAdditionalStates().entrySet()) {
222 if (!isAdditionalStateManaged(initial.getKey())) {
223
224
225 unmanagedStates.put(initial.getKey(), new TimeSpanMap<>(initial.getValue()));
226 }
227 }
228 }
229 }
230
231
232
233
234 protected void stateChanged(final FieldSpacecraftState<T> state) {
235 final AbsoluteDate date = state.getDate().toAbsoluteDate();
236 final boolean forward = date.durationFrom(getStartDate().toAbsoluteDate()) >= 0.0;
237 for (final Map.Entry<String, T[]> changed : state.getAdditionalStates().entrySet()) {
238 final TimeSpanMap<T[]> tsm = unmanagedStates.get(changed.getKey());
239 if (tsm != null) {
240
241 if (forward) {
242 tsm.addValidAfter(changed.getValue(), date);
243 } else {
244 tsm.addValidBefore(changed.getValue(), date);
245 }
246 }
247 }
248 }
249
250 }