1 /* Copyright 2002-2026 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 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.ode.events.Action;
21 import org.orekit.bodies.BodyShape;
22 import org.orekit.propagation.FieldSpacecraftState;
23 import org.orekit.propagation.events.functions.AltitudeEventFunction;
24 import org.orekit.propagation.events.functions.EventFunctionModifier;
25 import org.orekit.propagation.events.handlers.EventHandler;
26 import org.orekit.propagation.events.handlers.FieldEventHandler;
27 import org.orekit.propagation.events.handlers.FieldStopOnDecreasing;
28
29 /** Finder for satellite altitude crossing events.
30 * <p>This class finds altitude events (i.e. satellite crossing
31 * a predefined altitude level above ground).</p>
32 * <p>The default implementation behavior is to {@link Action#CONTINUE
33 * continue} propagation when ascending and to {@link Action#STOP stop}
34 * propagation when descending. This can be changed by calling
35 * {@link #withHandler(FieldEventHandler)} after construction.</p>
36 * @see org.orekit.propagation.FieldPropagator#addEventDetector(FieldEventDetector)
37 * @author Luc Maisonobe
38 * @since 9.0
39 * @param <T> type of the field elements
40 */
41 public class FieldAltitudeDetector<T extends CalculusFieldElement<T>> extends FieldAbstractGeographicalDetector<FieldAltitudeDetector<T>, T> {
42
43 /** Threshold altitude value (m). */
44 private final T altitude;
45
46 /** Build a new altitude detector.
47 * <p>This simple constructor takes default values for maximal checking
48 * interval ({@link #DEFAULT_MAX_CHECK}) and convergence threshold
49 * ({@link #DEFAULT_THRESHOLD}).</p>
50 * @param altitude threshold altitude value
51 * @param bodyShape body shape with respect to which altitude should be evaluated
52 */
53 public FieldAltitudeDetector(final T altitude, final BodyShape bodyShape) {
54 this(altitude.getField().getZero().newInstance(DEFAULT_MAX_CHECK),
55 altitude.getField().getZero().newInstance(DEFAULT_THRESHOLD),
56 altitude, bodyShape);
57 }
58
59 /** Build a new altitude detector.
60 * <p>This simple constructor takes default value for convergence threshold
61 * ({@link #DEFAULT_THRESHOLD}).</p>
62 * <p>The maximal interval between altitude checks should
63 * be smaller than the half duration of the minimal pass to handle,
64 * otherwise some short passes could be missed.</p>
65 * @param maxCheck maximal checking interval (s)
66 * @param altitude threshold altitude value (m)
67 * @param bodyShape body shape with respect to which altitude should be evaluated
68 */
69 public FieldAltitudeDetector(final T maxCheck,
70 final T altitude,
71 final BodyShape bodyShape) {
72 this(maxCheck, altitude.getField().getZero().newInstance(DEFAULT_THRESHOLD), altitude, bodyShape);
73 }
74
75 /** Build a new altitude detector.
76 * <p>The maximal interval between altitude checks should
77 * be smaller than the half duration of the minimal pass to handle,
78 * otherwise some short passes could be missed.</p>
79 * <p>The maximal interval between altitude checks should
80 * be smaller than the half duration of the minimal pass to handle,
81 * otherwise some short passes could be missed.</p>
82 * @param maxCheck maximal checking interval (s)
83 * @param threshold convergence threshold (s)
84 * @param altitude threshold altitude value (m)
85 * @param bodyShape body shape with respect to which altitude should be evaluated
86 */
87 public FieldAltitudeDetector(final T maxCheck,
88 final T threshold,
89 final T altitude,
90 final BodyShape bodyShape) {
91 this(new FieldEventDetectionSettings<>(maxCheck.getReal(), threshold, DEFAULT_MAX_ITER), new FieldStopOnDecreasing<>(),
92 altitude, bodyShape);
93 }
94
95 /** Protected constructor with full parameters.
96 * <p>
97 * This constructor is not public as users are expected to use the builder
98 * API with the various {@code withXxx()} methods to set up the instance
99 * in a readable manner without using a huge amount of parameters.
100 * </p>
101 * @param detectionSettings event detection settings
102 * @param handler event handler to call at event occurrences
103 * @param altitude threshold altitude value (m)
104 * @param bodyShape body shape with respect to which altitude should be evaluated
105 * @since 13.0
106 */
107 protected FieldAltitudeDetector(final FieldEventDetectionSettings<T> detectionSettings,
108 final FieldEventHandler<T> handler, final T altitude, final BodyShape bodyShape) {
109 super(EventFunctionModifier.addFieldValue(new AltitudeEventFunction(bodyShape, altitude.getReal()),
110 altitude.getAddendum()), detectionSettings, handler, bodyShape);
111 this.altitude = altitude;
112 }
113
114 /** {@inheritDoc} */
115 @Override
116 protected FieldAltitudeDetector<T> create(final FieldEventDetectionSettings<T> detectionSettings,
117 final FieldEventHandler<T> newHandler) {
118 return new FieldAltitudeDetector<>(detectionSettings, newHandler, altitude, getBodyShape());
119 }
120
121 /** Get the threshold altitude value.
122 * @return the threshold altitude value (m)
123 */
124 public T getAltitude() {
125 return altitude;
126 }
127
128 /** Compute the value of the switching function.
129 * This function measures the difference between the current altitude
130 * and the threshold altitude.
131 * @param s the current state information: date, kinematics, attitude
132 * @return value of the switching function
133 */
134 public T g(final FieldSpacecraftState<T> s) {
135 return getEventFunction().value(s);
136 }
137
138 /** {@inheritDoc} */
139 @Override
140 public AltitudeDetector toEventDetector(final EventHandler eventHandler) {
141 return new AltitudeDetector(altitude.getReal(), getBodyShape()).withHandler(eventHandler);
142 }
143 }