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
25 /**
26 * A detector that implements the {@link #g(SpacecraftState)} function using a lambda that
27 * can be set using {@link #withFunction(ToDoubleFunction)}.
28 *
29 * <p>For example, to create a simple date detector use:
30 *
31 * <pre>
32 * FunctionalDetector d = new FunctionalDetector()
33 * .withGFunction((s) -> s.getDate().durationFrom(triggerDate))
34 * .withMaxCheck(1e10);
35 * </pre>
36 *
37 * @author Evan Ward
38 * @since 9.2
39 */
40 public class FunctionalDetector extends AbstractDetector<FunctionalDetector> {
41
42 /** The g function. */
43 private final ToDoubleFunction<SpacecraftState> function;
44
45 /**
46 * Create an event detector with the default values. These are {@link
47 * #DEFAULT_MAXCHECK}, {@link #DEFAULT_THRESHOLD}, {@link #DEFAULT_MAX_ITER}, {@link
48 * ContinueOnEvent}, and a g function that is identically unity.
49 */
50 public FunctionalDetector() {
51 this(AdaptableInterval.of(DEFAULT_MAXCHECK), DEFAULT_THRESHOLD, DEFAULT_MAX_ITER,
52 new ContinueOnEvent(),
53 (ToDoubleFunction<SpacecraftState>) value -> 1.0);
54 }
55
56 /**
57 * Private constructor.
58 *
59 * @param maxCheck maximum checking interval
60 * @param threshold convergence threshold (s)
61 * @param maxIter maximum number of iterations in the event time search
62 * @param handler event handler to call at event occurrences
63 * @param function the switching function.
64 */
65 protected FunctionalDetector(final AdaptableInterval maxCheck,
66 final double threshold,
67 final int maxIter,
68 final EventHandler handler,
69 final ToDoubleFunction<SpacecraftState> function) {
70 super(maxCheck, threshold, maxIter, handler);
71 this.function = function;
72 }
73
74
75 @Override
76 public double g(final SpacecraftState s) {
77 return function.applyAsDouble(s);
78 }
79
80 @Override
81 protected FunctionalDetector create(
82 final AdaptableInterval newMaxCheck,
83 final double newThreshold,
84 final int newMaxIter,
85 final EventHandler newHandler) {
86
87 return new FunctionalDetector(newMaxCheck, newThreshold, newMaxIter, newHandler,
88 function);
89 }
90
91 /**
92 * Create a new event detector with a new g function, keeping all other attributes the
93 * same. It is recommended to use {@link #withMaxCheck(AdaptableInterval)} and {@link
94 * #withThreshold(double)} to set appropriate values for this g function.
95 *
96 * @param newGFunction the new g function.
97 * @return a new detector with the new g function.
98 */
99 public FunctionalDetector withFunction(
100 final ToDoubleFunction<SpacecraftState> newGFunction) {
101 return new FunctionalDetector(getMaxCheckInterval(), getThreshold(),
102 getMaxIterationCount(), getHandler(), newGFunction);
103 }
104
105 /**
106 * Get the switching function.
107 *
108 * @return the function used in {@link #g(SpacecraftState)}.
109 */
110 public ToDoubleFunction<SpacecraftState> getFunction() {
111 return function;
112 }
113
114 }