1 /* Copyright 2002-2025 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.handlers.EventHandler;
23 import org.orekit.propagation.events.intervals.AdaptableInterval;
24 import org.orekit.time.AbsoluteDate;
25
26 /** Common parts shared by several orbital events finders.
27 * @param <T> type of the detector
28 * @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
29 * @author Luc Maisonobe
30 */
31 public abstract class AbstractDetector<T extends AbstractDetector<T>> implements EventDetector {
32
33 /** Default maximum checking interval (s). */
34 public static final double DEFAULT_MAX_CHECK = EventDetectionSettings.DEFAULT_MAX_CHECK;
35
36 /** Default convergence threshold (s). */
37 public static final double DEFAULT_THRESHOLD = EventDetectionSettings.DEFAULT_THRESHOLD;
38
39 /** Default maximum number of iterations in the event time search. */
40 public static final int DEFAULT_MAX_ITER = EventDetectionSettings.DEFAULT_MAX_ITER;
41
42 /** Detection settings. */
43 private final EventDetectionSettings eventDetectionSettings;
44
45 /** Default handler for event overrides. */
46 private final EventHandler handler;
47
48 /** Propagation direction. */
49 private boolean forward;
50
51 /** Build a new instance.
52 * @param maxCheck maximum checking interval, must be strictly positive (s)
53 * @param threshold convergence threshold (s)
54 * @param maxIter maximum number of iterations in the event time search
55 * @param handler event handler to call at event occurrences
56 */
57 protected AbstractDetector(final double maxCheck, final double threshold, final int maxIter,
58 final EventHandler handler) {
59 this(new EventDetectionSettings(maxCheck, threshold, maxIter), handler);
60 }
61
62 /** Build a new instance.
63 * @param detectionSettings event detection settings
64 * @param handler event handler to call at event occurrences
65 * @since 12.2
66 */
67 protected AbstractDetector(final EventDetectionSettings detectionSettings, final EventHandler handler) {
68 checkStrictlyPositive(detectionSettings.getThreshold());
69 this.eventDetectionSettings = detectionSettings;
70 this.handler = handler;
71 this.forward = true;
72 }
73
74 /**
75 * Check if propagation is forward or not.
76 * @param state initial state
77 * @param targetDate target propagation date
78 * @return forward flag
79 * @since 13.0
80 */
81 public static boolean checkIfForward(final SpacecraftState state, final AbsoluteDate targetDate) {
82 return targetDate.durationFrom(state.getDate()) >= 0.0;
83 }
84
85 /** Check value is strictly positive.
86 * @param value value to check
87 * @exception OrekitException if value is not strictly positive
88 * @since 11.2
89 */
90 private void checkStrictlyPositive(final double value) throws OrekitException {
91 if (value <= 0.0) {
92 throw new OrekitException(OrekitMessages.NOT_STRICTLY_POSITIVE, value);
93 }
94 }
95
96 /**
97 * {@inheritDoc}
98 *
99 * <p> This implementation sets the direction of propagation and initializes the event
100 * handler. If a subclass overrides this method it should call {@code
101 * super.init(s0, t)}.
102 */
103 @Override
104 public void init(final SpacecraftState s0,
105 final AbsoluteDate t) {
106 EventDetector.super.init(s0, t);
107 forward = checkIfForward(s0, t);
108 }
109
110 /** {@inheritDoc} */
111 @Override
112 public EventDetectionSettings getDetectionSettings() {
113 return eventDetectionSettings;
114 }
115
116 /**
117 * Set up the maximum checking interval.
118 * <p>
119 * This will override a maximum checking interval if it has been configured previously.
120 * </p>
121 * @param newMaxCheck maximum checking interval (s)
122 * @return a new detector with updated configuration (the instance is not changed)
123 * @since 6.1
124 */
125 public T withMaxCheck(final double newMaxCheck) {
126 return withMaxCheck(AdaptableInterval.of(newMaxCheck));
127 }
128
129 /**
130 * Set up the maximum checking interval.
131 * <p>
132 * This will override a maximum checking interval if it has been configured previously.
133 * </p>
134 * @param newMaxCheck maximum checking interval (s)
135 * @return a new detector with updated configuration (the instance is not changed)
136 * @since 12.0
137 */
138 public T withMaxCheck(final AdaptableInterval newMaxCheck) {
139 return withDetectionSettings(new EventDetectionSettings(newMaxCheck, getThreshold(), getMaxIterationCount()));
140 }
141
142 /**
143 * Set up the maximum number of iterations in the event time search.
144 * <p>
145 * This will override a number of iterations if it has been configured previously.
146 * </p>
147 * @param newMaxIter maximum number of iterations in the event time search
148 * @return a new detector with updated configuration (the instance is not changed)
149 * @since 6.1
150 */
151 public T withMaxIter(final int newMaxIter) {
152 return withDetectionSettings(new EventDetectionSettings(getMaxCheckInterval(), getThreshold(), newMaxIter));
153 }
154
155 /**
156 * Set up the convergence threshold.
157 * <p>
158 * This will override a convergence threshold if it has been configured previously.
159 * </p>
160 * @param newThreshold convergence threshold (s)
161 * @return a new detector with updated configuration (the instance is not changed)
162 * @since 6.1
163 */
164 public T withThreshold(final double newThreshold) {
165 return withDetectionSettings(new EventDetectionSettings(getMaxCheckInterval(), newThreshold, getMaxIterationCount()));
166 }
167
168 /**
169 * Set up the event detection settings.
170 * <p>
171 * This will override settings previously configured.
172 * </p>
173 * @param newSettings new event detection settings
174 * @return a new detector with updated configuration (the instance is not changed)
175 * @since 12.2
176 */
177 public T withDetectionSettings(final EventDetectionSettings newSettings) {
178 return create(new EventDetectionSettings(newSettings.getMaxCheckInterval(), newSettings.getThreshold(), newSettings.getMaxIterationCount()),
179 getHandler());
180 }
181
182 /**
183 * Set up the event handler to call at event occurrences.
184 * <p>
185 * This will override a handler if it has been configured previously.
186 * </p>
187 * @param newHandler event handler to call at event occurrences
188 * @return a new detector with updated configuration (the instance is not changed)
189 * @since 6.1
190 */
191 public T withHandler(final EventHandler newHandler) {
192 return create(getDetectionSettings(), newHandler);
193 }
194
195 /** {@inheritDoc} */
196 @Override
197 public EventHandler getHandler() {
198 return handler;
199 }
200
201 /** Build a new instance.
202 * @param detectionSettings detection settings
203 * @param newHandler event handler to call at event occurrences
204 * @return a new instance of the appropriate sub-type
205 * @since 12.2
206 */
207 protected abstract T create(EventDetectionSettings detectionSettings, EventHandler newHandler);
208
209 /** Check if the current propagation is forward or backward.
210 * @return true if the current propagation is forward
211 * @since 7.2
212 */
213 public boolean isForward() {
214 return forward;
215 }
216
217 }