1 /* Copyright 2002-2026 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.propagation.events;
18
19 import org.orekit.errors.OrekitException;
20 import org.orekit.errors.OrekitMessages;
21 import org.orekit.propagation.SpacecraftState;
22 import org.orekit.propagation.events.functions.EventFunction;
23 import org.orekit.propagation.events.handlers.EventHandler;
24 import org.orekit.propagation.events.intervals.AdaptableInterval;
25 import org.orekit.time.AbsoluteDate;
26
27 /** Common parts shared by several events finders.
28 * It should only be implemented by detectors able to accept any handler.
29 * @param <T> type of the detector
30 * @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
31 * @author Luc Maisonobe
32 */
33 public abstract class AbstractDetector<T extends AbstractDetector<T>> implements EventDetector {
34
35 /** Default maximum checking interval (s). */
36 public static final double DEFAULT_MAX_CHECK = EventDetectionSettings.DEFAULT_MAX_CHECK;
37
38 /** Default convergence threshold (s). */
39 public static final double DEFAULT_THRESHOLD = EventDetectionSettings.DEFAULT_THRESHOLD;
40
41 /** Default maximum number of iterations in the event time search. */
42 public static final int DEFAULT_MAX_ITER = EventDetectionSettings.DEFAULT_MAX_ITER;
43
44 /** Detection settings. */
45 private final EventDetectionSettings eventDetectionSettings;
46
47 /** Handler for event overrides. */
48 private final EventHandler handler;
49
50 /** Default event function. */
51 private final EventFunction defaultEventFunction;
52
53 /** Propagation direction. */
54 private boolean forward = true;
55
56 /** Build a new instance.
57 * @param maxCheck maximum checking interval, must be strictly positive (s)
58 * @param threshold convergence threshold (s)
59 * @param maxIter maximum number of iterations in the event time search
60 * @param handler event handler to call at event occurrences
61 */
62 protected AbstractDetector(final double maxCheck, final double threshold, final int maxIter,
63 final EventHandler handler) {
64 this(new EventDetectionSettings(maxCheck, threshold, maxIter), handler);
65 }
66
67 /** Build a new instance.
68 * @param detectionSettings event detection settings
69 * @param handler event handler to call at event occurrences
70 * @since 12.2
71 */
72 protected AbstractDetector(final EventDetectionSettings detectionSettings, final EventHandler handler) {
73 checkStrictlyPositive(detectionSettings.getThreshold());
74 this.eventDetectionSettings = detectionSettings;
75 this.handler = handler;
76 this.defaultEventFunction = this::g;
77 }
78
79 /** Build a new instance.
80 * @param eventFunction event function
81 * @param detectionSettings event detection settings
82 * @param handler event handler to call at event occurrences
83 * @since 14.0
84 */
85 protected AbstractDetector(final EventFunction eventFunction,
86 final EventDetectionSettings detectionSettings,
87 final EventHandler handler) {
88 checkStrictlyPositive(detectionSettings.getThreshold());
89 this.eventDetectionSettings = detectionSettings;
90 this.handler = handler;
91 this.defaultEventFunction = eventFunction;
92 }
93
94 /**
95 * Check if propagation is forward or not.
96 * @param state initial state
97 * @param targetDate target propagation date
98 * @return forward flag
99 * @since 13.0
100 */
101 public static boolean checkIfForward(final SpacecraftState state, final AbsoluteDate targetDate) {
102 return targetDate.durationFrom(state.getDate()) >= 0.0;
103 }
104
105 /** Check value is strictly positive.
106 * @param value value to check
107 * @exception OrekitException if value is not strictly positive
108 * @since 11.2
109 */
110 private void checkStrictlyPositive(final double value) throws OrekitException {
111 if (value <= 0.0) {
112 throw new OrekitException(OrekitMessages.NOT_STRICTLY_POSITIVE, value);
113 }
114 }
115
116 /**
117 * {@inheritDoc}
118 *
119 * <p> This implementation sets the direction of propagation and initializes the event
120 * handler. If a subclass overrides this method it should call {@code
121 * super.init(s0, t)}.
122 */
123 @Override
124 public void init(final SpacecraftState s0,
125 final AbsoluteDate t) {
126 EventDetector.super.init(s0, t);
127 forward = checkIfForward(s0, t);
128 }
129
130 @Override
131 public EventFunction getEventFunction() {
132 return defaultEventFunction;
133 }
134
135 /** {@inheritDoc} */
136 @Override
137 public EventDetectionSettings getDetectionSettings() {
138 return eventDetectionSettings;
139 }
140
141 /**
142 * Set up the maximum checking interval.
143 * <p>
144 * This will override a maximum checking interval if it has been configured previously.
145 * </p>
146 * @param newMaxCheck maximum checking interval (s)
147 * @return a new detector with updated configuration (the instance is not changed)
148 * @since 6.1
149 */
150 public T withMaxCheck(final double newMaxCheck) {
151 return withMaxCheck(AdaptableInterval.of(newMaxCheck));
152 }
153
154 /**
155 * Set up the maximum checking interval.
156 * <p>
157 * This will override a maximum checking interval if it has been configured previously.
158 * </p>
159 * @param newMaxCheck maximum checking interval (s)
160 * @return a new detector with updated configuration (the instance is not changed)
161 * @since 12.0
162 */
163 public T withMaxCheck(final AdaptableInterval newMaxCheck) {
164 return withDetectionSettings(new EventDetectionSettings(newMaxCheck, getThreshold(), getMaxIterationCount()));
165 }
166
167 /**
168 * Set up the maximum number of iterations in the event time search.
169 * <p>
170 * This will override a number of iterations if it has been configured previously.
171 * </p>
172 * @param newMaxIter maximum number of iterations in the event time search
173 * @return a new detector with updated configuration (the instance is not changed)
174 * @since 6.1
175 */
176 public T withMaxIter(final int newMaxIter) {
177 return withDetectionSettings(new EventDetectionSettings(getMaxCheckInterval(), getThreshold(), newMaxIter));
178 }
179
180 /**
181 * Set up the convergence threshold.
182 * <p>
183 * This will override a convergence threshold if it has been configured previously.
184 * </p>
185 * @param newThreshold convergence threshold (s)
186 * @return a new detector with updated configuration (the instance is not changed)
187 * @since 6.1
188 */
189 public T withThreshold(final double newThreshold) {
190 return withDetectionSettings(new EventDetectionSettings(getMaxCheckInterval(), newThreshold, getMaxIterationCount()));
191 }
192
193 /**
194 * Set up the event detection settings.
195 * <p>
196 * This will override settings previously configured.
197 * </p>
198 * @param newSettings new event detection settings
199 * @return a new detector with updated configuration (the instance is not changed)
200 * @since 12.2
201 */
202 public T withDetectionSettings(final EventDetectionSettings newSettings) {
203 return create(new EventDetectionSettings(newSettings.getMaxCheckInterval(), newSettings.getThreshold(), newSettings.getMaxIterationCount()),
204 getHandler());
205 }
206
207 /**
208 * Set up the event handler to call at event occurrences.
209 * <p>
210 * This will override a handler if it has been configured previously.
211 * </p>
212 * @param newHandler event handler to call at event occurrences
213 * @return a new detector with updated configuration (the instance is not changed)
214 * @since 6.1
215 */
216 public T withHandler(final EventHandler newHandler) {
217 return create(getDetectionSettings(), newHandler);
218 }
219
220 /** {@inheritDoc} */
221 @Override
222 public EventHandler getHandler() {
223 return handler;
224 }
225
226 /** Build a new instance.
227 * @param detectionSettings detection settings
228 * @param newHandler event handler to call at event occurrences
229 * @return a new instance of the appropriate sub-type
230 * @since 12.2
231 */
232 protected abstract T create(EventDetectionSettings detectionSettings, EventHandler newHandler);
233
234 /** Check if the current propagation is forward or backward.
235 * @return true if the current propagation is forward
236 * @since 7.2
237 */
238 public boolean isForward() {
239 return forward;
240 }
241
242 }