1 /* Copyright 2002-2024 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_MAXCHECK}) 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_MAXCHECK),
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(FieldAdaptableInterval.of(maxCheck.getReal()), threshold, DEFAULT_MAX_ITER, new FieldStopOnDecreasing<T>(),
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 maxCheck maximum checking interval
104 * @param threshold convergence threshold (s)
105 * @param maxIter maximum number of iterations in the event time search
106 * @param handler event handler to call at event occurrences
107 * @param altitude threshold altitude value (m)
108 * @param bodyShape body shape with respect to which altitude should be evaluated
109 * @since 6.1
110 */
111 protected FieldAltitudeDetector(final FieldAdaptableInterval<T> maxCheck, final T threshold,
112 final int maxIter, final FieldEventHandler<T> handler,
113 final T altitude,
114 final BodyShape bodyShape) {
115 super(maxCheck, threshold, maxIter, handler);
116 this.altitude = altitude;
117 this.bodyShape = bodyShape;
118 }
119
120 /** {@inheritDoc} */
121 @Override
122 protected FieldAltitudeDetector<T> create(final FieldAdaptableInterval<T> newMaxCheck, final T newThreshold,
123 final int newMaxIter,
124 final FieldEventHandler<T> newHandler) {
125 return new FieldAltitudeDetector<>(newMaxCheck, newThreshold, newMaxIter, newHandler,
126 altitude, bodyShape);
127 }
128
129 /** Get the threshold altitude value.
130 * @return the threshold altitude value (m)
131 */
132 public T getAltitude() {
133 return altitude;
134 }
135
136 /** Get the body shape.
137 * @return the body shape
138 */
139 public BodyShape getBodyShape() {
140 return bodyShape;
141 }
142
143 /** Compute the value of the switching function.
144 * This function measures the difference between the current altitude
145 * and the threshold altitude.
146 * @param s the current state information: date, kinematics, attitude
147 * @return value of the switching function
148 */
149 public T g(final FieldSpacecraftState<T> s) {
150 final Frame bodyFrame = bodyShape.getBodyFrame();
151 final FieldGeodeticPoint<T> point = bodyShape.transform(s.getPosition(bodyFrame),
152 bodyFrame, s.getDate());
153 return point.getAltitude().subtract(altitude);
154 }
155
156 }