1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.events;
18
19 import java.util.List;
20 import java.util.stream.Collectors;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.Field;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.propagation.FieldSpacecraftState;
27 import org.orekit.propagation.events.functions.EventFunction;
28 import org.orekit.propagation.events.functions.TimeIntervalEventFunction;
29 import org.orekit.propagation.events.handlers.EventHandler;
30 import org.orekit.propagation.events.handlers.FieldEventHandler;
31 import org.orekit.propagation.events.handlers.FieldStopOnEvent;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.TimeInterval;
34 import org.orekit.utils.DateDriver;
35 import org.orekit.utils.ParameterDriver;
36 import org.orekit.utils.ParameterObserver;
37 import org.orekit.utils.TimeSpanMap;
38 import org.orekit.utils.TimeSpanMap.Span;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class FieldParameterDrivenDateIntervalDetector<T extends CalculusFieldElement<T>>
56 extends FieldAbstractDetector<FieldParameterDrivenDateIntervalDetector<T>, T> {
57
58
59 public static final String START_SUFFIX = "_START";
60
61
62 public static final String STOP_SUFFIX = "_STOP";
63
64
65 public static final String MEDIAN_SUFFIX = "_MEDIAN";
66
67
68 public static final String DURATION_SUFFIX = "_DURATION";
69
70
71 private final DateDriver start;
72
73
74 private final DateDriver stop;
75
76
77 private final DateDriver median;
78
79
80 private final ParameterDriver duration;
81
82
83
84
85
86
87
88 public FieldParameterDrivenDateIntervalDetector(final Field<T> field, final String prefix,
89 final AbsoluteDate refMedian, final double refDuration) {
90 this(field, prefix,
91 refMedian.shiftedBy(-0.5 * refDuration),
92 refMedian.shiftedBy(+0.5 * refDuration));
93 }
94
95
96
97
98
99
100
101 public FieldParameterDrivenDateIntervalDetector(final Field<T> field, final String prefix,
102 final AbsoluteDate refStart, final AbsoluteDate refStop) {
103 this(new FieldEventDetectionSettings<>(field, EventDetectionSettings.getDefaultEventDetectionSettings()),
104 new FieldStopOnEvent<>(),
105 new DateDriver(refStart, prefix + START_SUFFIX, true),
106 new DateDriver(refStop, prefix + STOP_SUFFIX, false),
107 new DateDriver(refStart.shiftedBy(0.5 * refStop.durationFrom(refStart)), prefix + MEDIAN_SUFFIX, true),
108 new ParameterDriver(prefix + DURATION_SUFFIX, refStop.durationFrom(refStart), 1.0, 0.0, Double.POSITIVE_INFINITY));
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 protected FieldParameterDrivenDateIntervalDetector(final FieldEventDetectionSettings<T> detectionSettings,
126 final FieldEventHandler<T> handler,
127 final DateDriver start, final DateDriver stop,
128 final DateDriver median, final ParameterDriver duration) {
129 super(detectionSettings, handler);
130 this.start = start;
131 this.stop = stop;
132 this.median = median;
133 this.duration = duration;
134
135
136 replaceBindingObserver(start, new StartObserver());
137 replaceBindingObserver(stop, new StopObserver());
138 replaceBindingObserver(median, new MedianObserver());
139 replaceBindingObserver(duration, new DurationObserver());
140
141 }
142
143
144
145
146
147 private void replaceBindingObserver(final ParameterDriver driver, final BindingObserver bindingObserver) {
148
149
150 final List<ParameterObserver> original = driver.
151 getObservers().
152 stream().
153 filter(observer -> observer instanceof FieldParameterDrivenDateIntervalDetector.BindingObserver).
154 collect(Collectors.toList());
155 original.forEach(driver::removeObserver);
156
157 driver.addObserver(bindingObserver);
158
159 }
160
161
162 @Override
163 protected FieldParameterDrivenDateIntervalDetector<T> create(final FieldEventDetectionSettings<T> detectionSettings,
164 final FieldEventHandler<T> newHandler) {
165 return new FieldParameterDrivenDateIntervalDetector<>(detectionSettings, newHandler,
166 start, stop, median, duration);
167 }
168
169
170
171
172
173
174
175
176
177 public DateDriver getStartDriver() {
178 return start;
179 }
180
181
182
183
184
185
186
187
188
189 public DateDriver getStopDriver() {
190 return stop;
191 }
192
193
194
195
196
197
198
199
200
201 public DateDriver getMedianDriver() {
202 return median;
203 }
204
205
206
207
208
209
210
211
212
213 public ParameterDriver getDurationDriver() {
214 return duration;
215 }
216
217 @Override
218 public EventFunction getEventFunction() {
219 return new ParameterDrivenDateIntervalEventFunction(start.getDate(), stop.getDate());
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234 @Override
235 public T g(final FieldSpacecraftState<T> s) {
236 return getEventFunction().value(s);
237 }
238
239
240 @Override
241 public ParameterDrivenDateIntervalDetector toEventDetector(final EventHandler eventHandler) {
242 return new ParameterDrivenDateIntervalDetector(getDetectionSettings().toEventDetectionSettings(), eventHandler,
243 getStartDriver(), getStopDriver(), getMedianDriver(), getDurationDriver());
244 }
245
246
247 private abstract class BindingObserver implements ParameterObserver {
248
249
250 @Override
251 public void valueChanged(final double previousValue, final ParameterDriver driver, final AbsoluteDate date) {
252 if (driver.isSelected()) {
253 setDelta(driver.getValue(date) - previousValue, date);
254 }
255 }
256
257
258 @Override
259 public void valueSpanMapChanged(final TimeSpanMap<Double> previousValue, final ParameterDriver driver) {
260 if (driver.isSelected()) {
261 for (Span<Double> span = driver.getValueSpanMap().getFirstSpan(); span != null; span = span.next()) {
262 setDelta(span.getData() - previousValue.get(span.getStart()), span.getStart());
263 }
264 }
265 }
266
267
268 @Override
269 public void selectionChanged(final boolean previousSelection, final ParameterDriver driver) {
270 if ((start.isSelected() || stop.isSelected()) &&
271 (median.isSelected() || duration.isSelected())) {
272 throw new OrekitException(OrekitMessages.INCONSISTENT_SELECTION,
273 start.getName(), stop.getName(),
274 median.getName(), duration.getName());
275 }
276 }
277
278
279
280
281
282 protected abstract void setDelta(double delta, AbsoluteDate date);
283
284 }
285
286
287 private class StartObserver extends BindingObserver {
288
289 @Override
290 protected void setDelta(final double delta, final AbsoluteDate date) {
291 median.setValue(median.getValue(date) + 0.5 * delta, date);
292 duration.setValue(duration.getValue(date) - delta, date);
293 }
294 }
295
296
297 private class StopObserver extends BindingObserver {
298
299 @Override
300 protected void setDelta(final double delta, final AbsoluteDate date) {
301 median.setValue(median.getValue(date) + 0.5 * delta, date);
302 duration.setValue(duration.getValue(date) + delta, date);
303 }
304 }
305
306
307 private class MedianObserver extends BindingObserver {
308
309 @Override
310 protected void setDelta(final double delta, final AbsoluteDate date) {
311 start.setValue(start.getValue(date) + delta, date);
312 stop.setValue(stop.getValue(date) + delta, date);
313 }
314 }
315
316
317 private class DurationObserver extends BindingObserver {
318
319 @Override
320 protected void setDelta(final double delta, final AbsoluteDate date) {
321 start.setValue(start.getValue(date) - 0.5 * delta, date);
322 stop.setValue(stop.getValue(date) + 0.5 * delta, date);
323 }
324 }
325
326 private static class ParameterDrivenDateIntervalEventFunction extends TimeIntervalEventFunction {
327
328
329
330
331
332
333 ParameterDrivenDateIntervalEventFunction(final AbsoluteDate startDate, final AbsoluteDate endDate) {
334 super(new TimeInterval() {
335
336 @Override
337 public AbsoluteDate getStartDate() {
338 return startDate;
339 }
340
341 @Override
342 public AbsoluteDate getEndDate() {
343 return endDate;
344 }
345 });
346 }
347 }
348 }