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;
18  
19  import java.util.function.ToDoubleFunction;
20  
21  import org.orekit.propagation.SpacecraftState;
22  import org.orekit.propagation.events.handlers.ContinueOnEvent;
23  import org.orekit.propagation.events.handlers.EventHandler;
24  import org.orekit.propagation.events.intervals.AdaptableInterval;
25  
26  /**
27   * A detector that implements the {@link #g(SpacecraftState)} function using a lambda that
28   * can be set using {@link #withFunction(ToDoubleFunction)}.
29   *
30   * <p>For example, to create a simple date detector use:
31   *
32   * <pre>
33   * FunctionalDetector d = new FunctionalDetector()
34   *     .withGFunction((s) -&gt; s.getDate().durationFrom(triggerDate))
35   *     .withMaxCheck(1e10);
36   * </pre>
37   *
38   * @author Evan Ward
39   * @since 9.2
40   */
41  public class FunctionalDetector extends AbstractDetector<FunctionalDetector> {
42  
43      /** The g function. */
44      private final ToDoubleFunction<SpacecraftState> function;
45  
46      /**
47       * Create an event detector with the default values. These are {@link
48       * #DEFAULT_MAX_CHECK}, {@link #DEFAULT_THRESHOLD}, {@link #DEFAULT_MAX_ITER}, {@link
49       * ContinueOnEvent}, and a g function that is identically unity.
50       */
51      public FunctionalDetector() {
52          this(EventDetectionSettings.getDefaultEventDetectionSettings(), new ContinueOnEvent(), value -> 1.0);
53      }
54  
55      /**
56       * Private constructor.
57       *
58       * @param detectionSettings event detection settings
59       * @param handler   event handler to call at event occurrences
60       * @param function  the switching function.
61       * @since 13.0
62       */
63      protected FunctionalDetector(final EventDetectionSettings detectionSettings,
64                                   final EventHandler handler,
65                                   final ToDoubleFunction<SpacecraftState> function) {
66          super(detectionSettings, handler);
67          this.function = function;
68      }
69  
70  
71      @Override
72      public double g(final SpacecraftState s) {
73          return function.applyAsDouble(s);
74      }
75  
76      @Override
77      protected FunctionalDetector create(final EventDetectionSettings detectionSettings, final EventHandler newHandler) {
78  
79          return new FunctionalDetector(detectionSettings, newHandler, function);
80      }
81  
82      /**
83       * Create a new event detector with a new g function, keeping all other attributes the
84       * same. It is recommended to use {@link #withMaxCheck(AdaptableInterval)} and {@link
85       * #withThreshold(double)} to set appropriate values for this g function.
86       *
87       * @param newGFunction the new g function.
88       * @return a new detector with the new g function.
89       */
90      public FunctionalDetector withFunction(final ToDoubleFunction<SpacecraftState> newGFunction) {
91          return new FunctionalDetector(getDetectionSettings(), getHandler(), newGFunction);
92      }
93  
94      /**
95       * Get the switching function.
96       *
97       * @return the function used in {@link #g(SpacecraftState)}.
98       */
99      public ToDoubleFunction<SpacecraftState> getFunction() {
100         return function;
101     }
102 
103 }