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