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
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
28 /** This class logs events detectors events during propagation.
29 *
30 * <p>As {@link FieldEventDetector events detectors} are triggered during
31 * orbit propagation, an event specific {@link
32 * FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean) eventOccurred}
33 * method is called. This class can be used to add a global logging
34 * feature registering all events with their corresponding states in
35 * a chronological sequence (or reverse-chronological if propagation
36 * occurs backward).
37 * <p>This class works by wrapping user-provided {@link FieldEventDetector
38 * events detectors} before they are registered to the propagator. The
39 * wrapper monitor the calls to {@link
40 * FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean) eventOccurred}
41 * and store the corresponding events as {@link FieldLoggedEvent} instances.
42 * After propagation is complete, the user can retrieve all the events
43 * that have occurred at once by calling method {@link #getLoggedEvents()}.</p>
44 *
45 * @author Luc Maisonobe
46 * @param <T> type of the field elements
47 */
48 public class FieldEventsLogger<T extends CalculusFieldElement<T>> {
49
50 /** List of occurred events. */
51 private final List<FieldLoggedEvent<T>> log;
52
53 /** Simple constructor.
54 * <p>
55 * Build an empty logger for events detectors.
56 * </p>
57 */
58 public FieldEventsLogger() {
59 log = new ArrayList<>();
60 }
61
62 /** Monitor an event detector.
63 * <p>
64 * In order to monitor an event detector, it must be wrapped thanks to
65 * this method as follows:
66 * </p>
67 * <pre>
68 * Propagator propagator = new XyzPropagator(...);
69 * EventsLogger logger = new EventsLogger();
70 * FieldEventDetector<T> detector = new UvwDetector(...);
71 * propagator.addEventDetector(logger.monitorDetector(detector));
72 * </pre>
73 * <p>
74 * Note that the event detector returned by the {@link
75 * FieldLoggedEvent#getEventDetector() getEventDetector} method in
76 * {@link FieldLoggedEvent FieldLoggedEvent} instances returned by {@link
77 * #getLoggedEvents()} are the {@code monitoredDetector} instances
78 * themselves, not the wrapping detector returned by this method.
79 * </p>
80 * @param monitoredDetector event detector to monitor
81 * @return the wrapping detector to add to the propagator
82 */
83 public FieldEventDetector<T> monitorDetector(final FieldEventDetector<T> monitoredDetector) {
84 return new FieldLoggingWrapper(monitoredDetector);
85 }
86
87 /** Clear the logged events.
88 */
89 public void clearLoggedEvents() {
90 log.clear();
91 }
92
93 /** Get an immutable copy of the logged events.
94 * <p>
95 * The copy is independent of the logger. It is preserved
96 * event if the {@link #clearLoggedEvents() clearLoggedEvents} method
97 * is called and the logger reused in another propagation.
98 * </p>
99 * @return an immutable copy of the logged events
100 */
101 public List<FieldLoggedEvent<T>> getLoggedEvents() {
102 return new ArrayList<>(log);
103 }
104
105 /** Class for logged events entries.
106 * @param <T> type of the field elements
107 */
108 public static class FieldLoggedEvent <T extends CalculusFieldElement<T>> {
109
110 /** Event detector triggered. */
111 private final FieldEventDetector<T> detector;
112
113 /** Triggering state. */
114 private final FieldSpacecraftState<T> state;
115
116 /** Increasing/decreasing status. */
117 private final boolean increasing;
118
119 /** Simple constructor.
120 * @param detectorN detector for event that was triggered
121 * @param stateN state at event trigger date
122 * @param increasingN indicator if the event switching function was increasing
123 * or decreasing at event occurrence date
124 */
125 private FieldLoggedEvent(final FieldEventDetector<T> detectorN, final FieldSpacecraftState<T> stateN,
126 final boolean increasingN) {
127 detector = detectorN;
128 state = stateN;
129 increasing = increasingN;
130 }
131
132 /** Get the event detector triggered.
133 * @return event detector triggered
134 */
135 public FieldEventDetector<T> getEventDetector() {
136 return detector;
137 }
138
139 /** Get the triggering state.
140 * @return triggering state
141 * @see FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean)
142 */
143 public FieldSpacecraftState<T> getState() {
144 return state;
145 }
146
147 /** Get the Increasing/decreasing status of the event.
148 * @return increasing/decreasing status of the event
149 * @see FieldEventHandler#eventOccurred(FieldSpacecraftState, FieldEventDetector, boolean)
150 */
151 public boolean isIncreasing() {
152 return increasing;
153 }
154
155 }
156
157 /** Internal wrapper for events detectors. */
158 private class FieldLoggingWrapper implements FieldDetectorModifier<T> {
159
160 /** Wrapped detector. */
161 private final FieldEventDetector<T> detector;
162
163 /** Simple constructor.
164 * @param detector events detector to wrap
165 */
166 FieldLoggingWrapper(final FieldEventDetector<T> detector) {
167 this.detector = detector;
168 }
169
170 @Override
171 public FieldEventDetector<T> getDetector() {
172 return detector;
173 }
174
175 /** Log an event.
176 * @param state state at event trigger date
177 * @param increasing indicator if the event switching function was increasing
178 */
179 public void logEvent(final FieldSpacecraftState<T> state, final boolean increasing) {
180 log.add(new FieldLoggedEvent<>(getDetector(), state, increasing));
181 }
182
183 /** {@inheritDoc} */
184 @Override
185 public FieldEventHandler<T> getHandler() {
186
187 final FieldEventHandler<T> handler = getDetector().getHandler();
188
189 return new FieldEventHandler<T>() {
190
191 /** {@inheritDoc} */
192 public Action eventOccurred(final FieldSpacecraftState<T> s,
193 final FieldEventDetector<T> d,
194 final boolean increasing) {
195 logEvent(s, increasing);
196 return handler.eventOccurred(s, getDetector(), increasing);
197 }
198
199 /** {@inheritDoc} */
200 @Override
201 public FieldSpacecraftState<T> resetState(final FieldEventDetector<T> d,
202 final FieldSpacecraftState<T> oldState) {
203 return handler.resetState(getDetector(), oldState);
204 }
205
206 };
207 }
208
209 }
210
211 }