1   /* Contributed in the public domain.
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.handlers;
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.ode.events.Action;
25  import org.orekit.propagation.FieldSpacecraftState;
26  import org.orekit.propagation.events.EventDetector;
27  import org.orekit.propagation.events.FieldEventDetector;
28  
29  /**
30   * Handler that will record every time an event occurs and always return {@link
31   * Action#CONTINUE}.
32   *
33   * <p> As this handler stores all observed events it may consume large amounts
34   * of memory depending on the duration of propagation and the frequency of events.
35   *
36   * @param <T> the type of {@link EventDetector} that this event handler will handle events
37   *            for.
38   * @param <E> the type of {@link CalculusFieldElement} to use instead of {@code double}.
39   * @author Evan Ward
40   * @see RecordAndContinue
41   * @since 9.3
42   */
43  public class FieldRecordAndContinue
44          <T extends FieldEventDetector<E>, E extends CalculusFieldElement<E>>
45          implements FieldEventHandler<T, E> {
46  
47      /** A single event detected during propagation. */
48      public static class Event<T, F extends CalculusFieldElement<F>> {
49  
50          /** The observed state. */
51          private final FieldSpacecraftState<F> state;
52          /** The detector. */
53          private final T detector;
54          /** The sign of the derivative of the g function. */
55          private final boolean increasing;
56  
57          /**
58           * Create a new event.
59           *
60           * @param detector   of the event.
61           * @param state      of the event.
62           * @param increasing if the g function is increasing.
63           */
64          private Event(final T detector,
65                        final FieldSpacecraftState<F> state,
66                        final boolean increasing) {
67              this.detector = detector;
68              this.state = state;
69              this.increasing = increasing;
70          }
71  
72          /**
73           * Get the detector.
74           *
75           * @return the detector that found the event.
76           * @see EventHandler#eventOccurred(SpacecraftState, EventDetector, boolean)
77           */
78          public T getDetector() {
79              return detector;
80          }
81  
82          /**
83           * Is the g() function increasing?
84           *
85           * @return if the sign of the derivative of the g function is positive (true) or
86           * negative (false).
87           * @see EventHandler#eventOccurred(SpacecraftState, EventDetector, boolean)
88           */
89          public boolean isIncreasing() {
90              return increasing;
91          }
92  
93          /**
94           * Get the spacecraft's state at the event.
95           *
96           * @return the satellite's state when the event was triggered.
97           * @see EventHandler#eventOccurred(SpacecraftState, EventDetector, boolean)
98           */
99          public FieldSpacecraftState<F> getState() {
100             return state;
101         }
102 
103         @Override
104         public String toString() {
105             return "Event{" +
106                     "state=" + state +
107                     ", increasing=" + increasing +
108                     ", detector=" + detector +
109                     '}';
110         }
111     }
112 
113     /** Observed events. */
114     private final List<Event<T, E>> events;
115 
116     /** Create a new handler using an {@link ArrayList} to store events. */
117     public FieldRecordAndContinue() {
118         this(new ArrayList<>());
119     }
120 
121     /**
122      * Create a handler using the given collection to store events.
123      *
124      * @param events collection.
125      */
126     public FieldRecordAndContinue(final List<Event<T, E>> events) {
127         this.events = events;
128     }
129 
130     /**
131      * Get the events passed to this handler.
132      *
133      * <p> Note the returned list of events is in the order the events were
134      * passed to this handler by calling {@link #eventOccurred(FieldSpacecraftState,
135      * FieldEventDetector, boolean)}. This may or may not be chronological order.
136      *
137      * <p> Also not that this method returns a view of the internal collection
138      * used to store events and calling any of this handler's methods may modify both the
139      * underlying collection and the returned view. If a snapshot of the events up to a
140      * certain point is needed create a copy of the returned collection.
141      *
142      * @return the events observed by the handler in the order they were observed.
143      */
144     public List<Event<T, E>> getEvents() {
145         return Collections.unmodifiableList(this.events);
146     }
147 
148     /** Clear all stored events. */
149     public void clear() {
150         this.events.clear();
151     }
152 
153     @Override
154     public Action eventOccurred(final FieldSpacecraftState<E> s,
155                                 final T detector,
156                                 final boolean increasing) {
157         events.add(new Event<>(detector, s, increasing));
158         return Action.CONTINUE;
159     }
160 
161 }