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