1 /* Copyright 2002-2024 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
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.ode.events.Action;
25 import org.orekit.propagation.FieldSpacecraftState;
26 import org.orekit.propagation.events.handlers.FieldEventHandler;
27 import org.orekit.time.FieldAbsoluteDate;
28
29 /** This class logs events detectors events during propagation.
30 *
31 * <p>As {@link FieldEventDetector events detectors} are triggered during
32 * orbit propagation, an event specific {@link
33 * FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean) eventOccurred}
34 * method is called. This class can be used to add a global logging
35 * feature registering all events with their corresponding states in
36 * a chronological sequence (or reverse-chronological if propagation
37 * occurs backward).
38 * <p>This class works by wrapping user-provided {@link FieldEventDetector
39 * events detectors} before they are registered to the propagator. The
40 * wrapper monitor the calls to {@link
41 * FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean) eventOccurred}
42 * and store the corresponding events as {@link FieldLoggedEvent} instances.
43 * After propagation is complete, the user can retrieve all the events
44 * that have occurred at once by calling method {@link #getLoggedEvents()}.</p>
45 *
46 * @author Luc Maisonobe
47 * @param <T> type of the field elements
48 */
49 public class FieldEventsLogger<T extends CalculusFieldElement<T>> {
50
51
52
53 /** List of occurred events. */
54 private final List<FieldLoggedEvent<T>> log;
55
56 /** Simple constructor.
57 * <p>
58 * Build an empty logger for events detectors.
59 * </p>
60 */
61 public FieldEventsLogger() {
62 log = new ArrayList<FieldEventsLogger.FieldLoggedEvent<T>>();
63 }
64
65 /** Monitor an event detector.
66 * <p>
67 * In order to monitor an event detector, it must be wrapped thanks to
68 * this method as follows:
69 * </p>
70 * <pre>
71 * Propagator propagator = new XyzPropagator(...);
72 * EventsLogger logger = new EventsLogger();
73 * FieldEventDetector<T> detector = new UvwDetector(...);
74 * propagator.addEventDetector(logger.monitorDetector(detector));
75 * </pre>
76 * <p>
77 * Note that the event detector returned by the {@link
78 * FieldLoggedEvent#getEventDetector() getEventDetector} method in
79 * {@link FieldLoggedEvent FieldLoggedEvent} instances returned by {@link
80 * #getLoggedEvents()} are the {@code monitoredDetector} instances
81 * themselves, not the wrapping detector returned by this method.
82 * </p>
83 * @param monitoredDetector event detector to monitor
84 * @return the wrapping detector to add to the propagator
85 */
86 public FieldAbstractDetector<FieldLoggingWrapper, T> monitorDetector(final FieldEventDetector<T> monitoredDetector) {
87 return new FieldLoggingWrapper(monitoredDetector);
88 }
89
90 /** Clear the logged events.
91 */
92 public void clearLoggedEvents() {
93 log.clear();
94 }
95
96 /** Get an immutable copy of the logged events.
97 * <p>
98 * The copy is independent of the logger. It is preserved
99 * event if the {@link #clearLoggedEvents() clearLoggedEvents} method
100 * is called and the logger reused in another propagation.
101 * </p>
102 * @return an immutable copy of the logged events
103 */
104 public List<FieldLoggedEvent<T>> getLoggedEvents() {
105 return new ArrayList<FieldEventsLogger.FieldLoggedEvent<T>>(log);
106 }
107
108 /** Class for logged events entries.
109 * @param <T> type of the field elements
110 */
111 public static class FieldLoggedEvent <T extends CalculusFieldElement<T>> {
112
113 /** Event detector triggered. */
114 private final FieldEventDetector<T> detector;
115
116 /** Triggering state. */
117 private final FieldSpacecraftState<T> state;
118
119 /** Increasing/decreasing status. */
120 private final boolean increasing;
121
122 /** Simple constructor.
123 * @param detectorN detector for event that was triggered
124 * @param stateN state at event trigger date
125 * @param increasingN indicator if the event switching function was increasing
126 * or decreasing at event occurrence date
127 */
128 private FieldLoggedEvent(final FieldEventDetector<T> detectorN, final FieldSpacecraftState<T> stateN, final boolean increasingN) {
129 detector = detectorN;
130 state = stateN;
131 increasing = increasingN;
132 }
133
134 /** Get the event detector triggered.
135 * @return event detector triggered
136 */
137 public FieldEventDetector<T> getEventDetector() {
138 return detector;
139 }
140
141 /** Get the triggering state.
142 * @return triggering state
143 * @see FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean)
144 */
145 public FieldSpacecraftState<T> getState() {
146 return state;
147 }
148
149 /** Get the Increasing/decreasing status of the event.
150 * @return increasing/decreasing status of the event
151 * @see FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean)
152 */
153 public boolean isIncreasing() {
154 return increasing;
155 }
156
157 }
158
159 /** Internal wrapper for events detectors. */
160 private class FieldLoggingWrapper extends FieldAbstractDetector<FieldLoggingWrapper, T> {
161
162 /** Wrapped events detector. */
163 private final FieldEventDetector<T> detector;
164
165 /** Simple constructor.
166 * @param detector events detector to wrap
167 */
168 FieldLoggingWrapper(final FieldEventDetector<T> detector) {
169 this(detector.getMaxCheckInterval(), detector.getThreshold(),
170 detector.getMaxIterationCount(), null,
171 detector);
172 }
173
174 /** Private constructor with full parameters.
175 * <p>
176 * This constructor is private as users are expected to use the builder
177 * API with the various {@code withXxx()} methods to set up the instance
178 * in a readable manner without using a huge amount of parameters.
179 * </p>
180 * @param maxCheck maximum checking interval
181 * @param threshold convergence threshold (s)
182 * @param maxIter maximum number of iterations in the event time search
183 * @param handler event handler to call at event occurrences
184 * @param detector events detector to wrap
185 * @since 6.1
186 */
187 private FieldLoggingWrapper(final FieldAdaptableInterval<T> maxCheck, final T threshold,
188 final int maxIter, final FieldEventHandler<T> handler,
189 final FieldEventDetector<T> detector) {
190 super(maxCheck, threshold, maxIter, handler);
191 this.detector = detector;
192 }
193
194 /** {@inheritDoc} */
195 @Override
196 protected FieldLoggingWrapper create(final FieldAdaptableInterval<T> newMaxCheck, final T newThreshold,
197 final int newMaxIter, final FieldEventHandler<T> newHandler) {
198 return new FieldLoggingWrapper(newMaxCheck, newThreshold, newMaxIter, newHandler, detector);
199 }
200
201 /** Log an event.
202 * @param state state at event trigger date
203 * @param increasing indicator if the event switching function was increasing
204 */
205 public void logEvent(final FieldSpacecraftState<T> state, final boolean increasing) {
206 log.add(new FieldLoggedEvent<>(detector, state, increasing));
207 }
208
209 /** {@inheritDoc} */
210 public void init(final FieldSpacecraftState<T> s0,
211 final FieldAbsoluteDate<T> t) {
212 super.init(s0, t);
213 detector.init(s0, t);
214 }
215
216 /** {@inheritDoc} */
217 public T g(final FieldSpacecraftState<T> s) {
218 return detector.g(s);
219 }
220
221 /** {@inheritDoc} */
222 public FieldEventHandler<T> getHandler() {
223
224 final FieldEventHandler<T> handler = detector.getHandler();
225
226 return new FieldEventHandler<T>() {
227
228 /** {@inheritDoc} */
229 public Action eventOccurred(final FieldSpacecraftState<T> s,
230 final FieldEventDetector<T> d,
231 final boolean increasing) {
232 logEvent(s, increasing);
233 return handler.eventOccurred(s, detector, increasing);
234 }
235
236 /** {@inheritDoc} */
237 @Override
238 public FieldSpacecraftState<T> resetState(final FieldEventDetector<T> d,
239 final FieldSpacecraftState<T> oldState) {
240 return handler.resetState(detector, oldState);
241 }
242
243 };
244 }
245
246 }
247
248 }