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