1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.maneuvers.trigger;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.hipparchus.CalculusFieldElement;
25 import org.hipparchus.Field;
26 import org.hipparchus.ode.events.Action;
27 import org.orekit.propagation.FieldSpacecraftState;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.propagation.events.EventDetector;
30 import org.orekit.propagation.events.FieldEventDetector;
31 import org.orekit.propagation.events.handlers.EventHandler;
32 import org.orekit.propagation.events.handlers.FieldEventHandler;
33 import org.orekit.time.AbsoluteDate;
34 import org.orekit.time.FieldAbsoluteDate;
35 import org.orekit.utils.TimeSpanMap;
36
37
38
39
40
41 public abstract class AbstractManeuverTriggers implements ResettableManeuverTriggers {
42
43
44 private TimeSpanMap<Boolean> firings;
45
46
47 private boolean forward;
48
49
50 private final List<ManeuverTriggersResetter> resetters;
51
52
53 private final Map<Field<? extends CalculusFieldElement<?>>, List<FieldManeuverTriggersResetter<?>>> fieldResetters;
54
55
56
57 protected AbstractManeuverTriggers() {
58 this.firings = new TimeSpanMap<>(Boolean.FALSE);
59 this.resetters = new ArrayList<>();
60 this.fieldResetters = new HashMap<>();
61 }
62
63
64 @Override
65 public void init(final SpacecraftState initialState, final AbsoluteDate target) {
66
67 forward = target.isAfterOrEqualTo(initialState);
68 firings = new TimeSpanMap<>(Boolean.FALSE);
69 initializeResetters(initialState, target);
70
71 if (isFiringOnInitialState(initialState, forward)) {
72 if (forward) {
73 firings.addValidAfter(Boolean.TRUE, initialState.getDate(), false);
74 } else {
75 firings.addValidBefore(Boolean.TRUE, initialState.getDate(), false);
76 }
77 }
78
79 }
80
81
82 @SuppressWarnings("unchecked")
83 @Override
84 public <T extends CalculusFieldElement<T>> void init(final FieldSpacecraftState<T> initialState, final FieldAbsoluteDate<T> target) {
85
86 forward = target.isAfterOrEqualTo(initialState);
87 firings = new TimeSpanMap<>(Boolean.FALSE);
88
89 final List<FieldManeuverTriggersResetter<?>> list = fieldResetters.get(initialState.getDate().getField());
90 if (list != null) {
91 for (FieldManeuverTriggersResetter<?> r : list) {
92 ((FieldManeuverTriggersResetter<T>) r).init(initialState, target);
93 }
94 }
95
96 if (isFiringOnInitialState(initialState.toSpacecraftState(), forward)) {
97 if (forward) {
98 firings.addValidAfter(Boolean.TRUE, initialState.getDate().toAbsoluteDate(), false);
99 } else {
100 firings.addValidBefore(Boolean.TRUE, initialState.getDate().toAbsoluteDate(), false);
101 }
102 }
103
104 }
105
106
107
108
109
110
111
112
113
114 protected abstract boolean isFiringOnInitialState(SpacecraftState initialState, boolean isForward);
115
116
117 @Override
118 public boolean isFiring(final AbsoluteDate date, final double[] parameters) {
119 return firings.get(date);
120 }
121
122
123 @Override
124 public <S extends CalculusFieldElement<S>> boolean isFiring(final FieldAbsoluteDate<S> date, final S[] parameters) {
125 return firings.get(date.toAbsoluteDate());
126 }
127
128
129
130
131 public TimeSpanMap<Boolean> getFirings() {
132 return firings;
133 }
134
135
136 @Override
137 public void addResetter(final ManeuverTriggersResetter resetter) {
138 resetters.add(resetter);
139 }
140
141
142 @Override
143 public <T extends CalculusFieldElement<T>> void addResetter(final Field<T> field, final FieldManeuverTriggersResetter<T> resetter) {
144
145
146 final List<FieldManeuverTriggersResetter<?>> list = fieldResetters.computeIfAbsent(field, k -> new ArrayList<>());
147
148
149 list.add(resetter);
150
151 }
152
153
154
155
156
157 protected void initializeResetters(final SpacecraftState initialState, final AbsoluteDate target) {
158 for (final ManeuverTriggersResetter r : resetters) {
159 r.init(initialState, target);
160 }
161 }
162
163
164
165
166
167 protected void notifyResetters(final SpacecraftState state, final boolean start) {
168 for (final ManeuverTriggersResetter r : resetters) {
169 r.maneuverTriggered(state, start);
170 }
171 }
172
173
174
175
176
177 protected SpacecraftState applyResetters(final SpacecraftState state) {
178 SpacecraftState reset = state;
179 for (final ManeuverTriggersResetter r : resetters) {
180 reset = r.resetState(reset);
181 }
182 return reset;
183 }
184
185
186
187
188
189
190 protected <T extends CalculusFieldElement<T>> void initializeResetters(final FieldSpacecraftState<T> initialState, final FieldAbsoluteDate<T> target) {
191 final List<FieldManeuverTriggersResetter<?>> list = fieldResetters.get(initialState.getDate().getField());
192 if (list != null) {
193 for (final FieldManeuverTriggersResetter<?> r : list) {
194 @SuppressWarnings("unchecked")
195 final FieldManeuverTriggersResetter<T> tr = (FieldManeuverTriggersResetter<T>) r;
196 tr.init(initialState, target);
197 }
198 }
199 }
200
201
202
203
204
205
206 protected <T extends CalculusFieldElement<T>> void notifyResetters(final FieldSpacecraftState<T> state, final boolean start) {
207 final List<FieldManeuverTriggersResetter<?>> list = fieldResetters.get(state.getDate().getField());
208 if (list != null) {
209 for (final FieldManeuverTriggersResetter<?> r : list) {
210 @SuppressWarnings("unchecked")
211 final FieldManeuverTriggersResetter<T> tr = (FieldManeuverTriggersResetter<T>) r;
212 tr.maneuverTriggered(state, start);
213 }
214 }
215 }
216
217
218
219
220
221
222 protected <T extends CalculusFieldElement<T>> FieldSpacecraftState<T>
223 applyResetters(final FieldSpacecraftState<T> state) {
224 FieldSpacecraftState<T> reset = state;
225 final List<FieldManeuverTriggersResetter<?>> list = fieldResetters.get(state.getDate().getField());
226 if (list != null) {
227 for (final FieldManeuverTriggersResetter<?> r : list) {
228 @SuppressWarnings("unchecked")
229 final FieldManeuverTriggersResetter<T> tr = (FieldManeuverTriggersResetter<T>) r;
230 reset = tr.resetState(reset);
231 }
232 }
233 return reset;
234 }
235
236
237
238
239 protected abstract class TriggerHandler implements EventHandler {
240
241
242 private boolean forward;
243
244
245 private SpacecraftState lastState;
246
247
248 private SpacecraftState lastResetState;
249
250
251 @Override
252 public void init(final SpacecraftState initialState, final AbsoluteDate target, final EventDetector detector) {
253 forward = target.isAfterOrEqualTo(initialState);
254 lastState = null;
255 lastResetState = null;
256 initializeResetters(initialState, target);
257 }
258
259
260
261
262
263
264
265 protected Action determineAction(final EventDetector detector, final SpacecraftState oldState) {
266 final SpacecraftState resetState = resetState(detector, oldState);
267 if (resetState == oldState) {
268 return Action.RESET_DERIVATIVES;
269 } else {
270 return Action.RESET_STATE;
271 }
272 }
273
274
275 @Override
276 public SpacecraftState resetState(final EventDetector detector, final SpacecraftState oldState) {
277 if (lastState != oldState) {
278 lastResetState = applyResetters(oldState);
279 lastState = oldState;
280 }
281 return lastResetState;
282 }
283
284
285
286
287
288 protected boolean isForward() {
289 return forward;
290 }
291 }
292
293
294
295
296
297 protected abstract class FieldTriggerHandler<S extends CalculusFieldElement<S>> implements FieldEventHandler<S> {
298
299
300 private boolean forward;
301
302
303 private FieldSpacecraftState<S> lastState;
304
305
306 private FieldSpacecraftState<S> lastResetState;
307
308
309 @Override
310 public void init(final FieldSpacecraftState<S> initialState,
311 final FieldAbsoluteDate<S> target,
312 final FieldEventDetector<S> detector) {
313 forward = target.isAfterOrEqualTo(initialState);
314 lastState = null;
315 lastResetState = null;
316 initializeResetters(initialState, target);
317 }
318
319
320
321
322
323
324
325 protected Action determineAction(final FieldEventDetector<S> detector, final FieldSpacecraftState<S> oldState) {
326 final FieldSpacecraftState<S> resetState = resetState(detector, oldState);
327 if (resetState == oldState) {
328 return Action.RESET_DERIVATIVES;
329 } else {
330 return Action.RESET_STATE;
331 }
332 }
333
334
335 @Override
336 public FieldSpacecraftState<S> resetState(final FieldEventDetector<S> detector, final FieldSpacecraftState<S> oldState) {
337 if (lastState != oldState) {
338 lastResetState = applyResetters(oldState);
339 lastState = oldState;
340 }
341 return lastResetState;
342 }
343
344
345
346
347
348 protected boolean isForward() {
349 return forward;
350 }
351 }
352 }