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.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.Field;
25 import org.hipparchus.ode.events.Action;
26 import org.orekit.errors.OrekitIllegalArgumentException;
27 import org.orekit.errors.OrekitMessages;
28 import org.orekit.propagation.FieldSpacecraftState;
29 import org.orekit.propagation.events.handlers.FieldEventHandler;
30 import org.orekit.propagation.events.handlers.FieldStopOnEvent;
31 import org.orekit.propagation.events.intervals.DateDetectionAdaptableIntervalFactory;
32 import org.orekit.time.FieldAbsoluteDate;
33 import org.orekit.time.FieldTimeStamped;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class FieldDateDetector<T extends CalculusFieldElement<T>> extends FieldAbstractDetector<FieldDateDetector<T>, T>
52 implements FieldTimeStamped<T> {
53
54
55
56
57 public static final double DEFAULT_MAX_CHECK = DateDetector.DEFAULT_MAX_CHECK;
58
59
60
61
62 public static final double DEFAULT_MIN_GAP = DateDetector.DEFAULT_MIN_GAP;
63
64
65
66
67 public static final double DEFAULT_THRESHOLD = DateDetector.DEFAULT_THRESHOLD;
68
69
70
71
72 private final double minGap;
73
74
75 private FieldAbsoluteDate<T> gDate;
76
77
78 private final ArrayList<FieldEventDate<T>> eventDateList;
79
80
81 private int currentIndex;
82
83
84
85
86
87 public FieldDateDetector(final FieldAbsoluteDate<T> fieldAbsoluteDate) {
88 this(new FieldEventDetectionSettings<>(DEFAULT_MAX_CHECK, fieldAbsoluteDate.getField().getZero().newInstance(DEFAULT_THRESHOLD),
89 DEFAULT_MAX_ITER), new FieldStopOnEvent<>(), DEFAULT_MIN_GAP, fieldAbsoluteDate);
90 }
91
92
93
94
95
96
97
98
99
100 @SafeVarargs
101 public FieldDateDetector(final Field<T> field, final FieldTimeStamped<T>... dates) {
102 this(new FieldEventDetectionSettings<>(DateDetectionAdaptableIntervalFactory.getDatesDetectionFieldConstantInterval(dates),
103 field.getZero().newInstance(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER), new FieldStopOnEvent<>(), DEFAULT_MIN_GAP, dates);
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117 @SafeVarargs
118 protected FieldDateDetector(final FieldEventDetectionSettings<T> detectionSettings,
119 final FieldEventHandler<T> handler, final double minGap,
120 final FieldTimeStamped<T>... dates) {
121 super(detectionSettings, handler);
122 this.currentIndex = -1;
123 this.gDate = null;
124 this.eventDateList = new ArrayList<>(dates.length);
125 for (final FieldTimeStamped<T> ts : dates) {
126 addEventDate(ts.getDate());
127 }
128 this.minGap = minGap;
129 }
130
131
132
133
134
135
136
137 public FieldDateDetector<T> withMinGap(final double newMinGap) {
138 @SuppressWarnings("unchecked")
139 final FieldTimeStamped<T>[] dates = eventDateList.toArray(new FieldEventDate[0]);
140 return new FieldDateDetector<>(getDetectionSettings(), getHandler(), newMinGap, dates);
141 }
142
143
144 @Override
145 protected FieldDateDetector<T> create(final FieldEventDetectionSettings<T> detectionSettings,
146 final FieldEventHandler<T> newHandler) {
147 @SuppressWarnings("unchecked")
148 final FieldTimeStamped<T>[] dates = eventDateList.toArray(new FieldEventDate[0]);
149 return new FieldDateDetector<>(detectionSettings, newHandler, minGap, dates);
150 }
151
152
153
154
155
156 public List<FieldTimeStamped<T>> getDates() {
157 return Collections.unmodifiableList(eventDateList);
158 }
159
160
161
162
163
164
165 public T g(final FieldSpacecraftState<T> s) {
166 gDate = s.getDate();
167 if (currentIndex < 0) {
168 return s.getMass().getField().getZero().newInstance(-1);
169 } else {
170 final FieldEventDate<T> event = getClosest(gDate);
171 return event.isgIncrease() ? gDate.durationFrom(event.getDate()) : event.getDate().durationFrom(gDate);
172 }
173 }
174
175
176
177
178 public FieldAbsoluteDate<T> getDate() {
179 return currentIndex < 0 ? null : eventDateList.get(currentIndex).getDate();
180 }
181
182
183
184
185
186
187
188
189
190
191
192 public void addEventDate(final FieldAbsoluteDate<T> target) throws IllegalArgumentException {
193 final boolean increasing;
194 if (currentIndex < 0) {
195 increasing = (gDate == null) ? true : target.durationFrom(gDate).getReal() > 0.0;
196 currentIndex = 0;
197 eventDateList.add(new FieldEventDate<>(target, increasing));
198 } else {
199 final int lastIndex = eventDateList.size() - 1;
200 final FieldAbsoluteDate<T> firstDate = eventDateList.get(0).getDate();
201 final FieldAbsoluteDate<T> lastDate = eventDateList.get(lastIndex).getDate();
202 if (firstDate.durationFrom(target).getReal() > minGap) {
203 increasing = !eventDateList.get(0).isgIncrease();
204 eventDateList.add(0, new FieldEventDate<>(target, increasing));
205 currentIndex++;
206 } else if (target.durationFrom(lastDate).getReal() > minGap) {
207 increasing = !eventDateList.get(lastIndex).isgIncrease();
208 eventDateList.add(new FieldEventDate<>(target, increasing));
209 } else {
210 throw new OrekitIllegalArgumentException(OrekitMessages.EVENT_DATE_TOO_CLOSE,
211 target,
212 firstDate,
213 lastDate,
214 minGap,
215 firstDate.durationFrom(target),
216 target.durationFrom(lastDate));
217 }
218 }
219 }
220
221
222
223
224
225 private FieldEventDate<T> getClosest(final FieldAbsoluteDate<T> target) {
226 final T dt = target.durationFrom(eventDateList.get(currentIndex).getDate());
227 if (dt.getReal() < 0.0 && currentIndex > 0) {
228 boolean found = false;
229 while (currentIndex > 0 && !found) {
230 if (target.durationFrom(eventDateList.get(currentIndex - 1).getDate()).getReal() < eventDateList.get(currentIndex).getDate().durationFrom(target).getReal()) {
231 currentIndex--;
232 } else {
233 found = true;
234 }
235 }
236 } else if (dt.getReal() > 0.0 && currentIndex < eventDateList.size() - 1) {
237 final int maxIndex = eventDateList.size() - 1;
238 boolean found = false;
239 while (currentIndex < maxIndex && !found) {
240 if (target.durationFrom(eventDateList.get(currentIndex + 1).getDate()).getReal() > eventDateList.get(currentIndex).getDate().durationFrom(target).getReal()) {
241 currentIndex++;
242 } else {
243 found = true;
244 }
245 }
246 }
247 return eventDateList.get(currentIndex);
248 }
249
250
251 private static class FieldEventDate<T extends CalculusFieldElement<T>> implements FieldTimeStamped<T> {
252
253
254 private final FieldAbsoluteDate<T> eventDate;
255
256
257 private final boolean gIncrease;
258
259
260
261
262
263 FieldEventDate(final FieldAbsoluteDate<T> date, final boolean increase) {
264 this.eventDate = date;
265 this.gIncrease = increase;
266 }
267
268
269
270
271 public FieldAbsoluteDate<T> getDate() {
272 return eventDate;
273 }
274
275
276
277
278 public boolean isgIncrease() {
279 return gIncrease;
280 }
281
282 }
283
284 }