1 /* Copyright 2002-2021 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 import org.orekit.utils.PVCoordinates;
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(EventHandler)} after construction.</p>
35 * @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
36 * @author Luc Maisonobe
37 */
38 public class AltitudeDetector extends AbstractDetector<AltitudeDetector> {
39
40 /** Threshold altitude value (m). */
41 private final double altitude;
42
43 /** Body shape with respect to which altitude should be evaluated. */
44 private final BodyShape bodyShape;
45
46 /** Build a new altitude detector.
47 * <p>This simple constructor takes default values for maximal checking
48 * interval ({@link #DEFAULT_MAXCHECK}) 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 AltitudeDetector(final double altitude, final BodyShape bodyShape) {
54 this(DEFAULT_MAXCHECK, DEFAULT_THRESHOLD, altitude, bodyShape);
55 }
56
57 /** Build a new altitude detector.
58 * <p>This simple constructor takes default value for convergence threshold
59 * ({@link #DEFAULT_THRESHOLD}).</p>
60 * <p>The maximal interval between altitude checks should
61 * be smaller than the half duration of the minimal pass to handle,
62 * otherwise some short passes could be missed.</p>
63 * @param maxCheck maximal checking interval (s)
64 * @param altitude threshold altitude value (m)
65 * @param bodyShape body shape with respect to which altitude should be evaluated
66 */
67 public AltitudeDetector(final double maxCheck,
68 final double altitude,
69 final BodyShape bodyShape) {
70 this(maxCheck, DEFAULT_THRESHOLD, altitude, bodyShape);
71 }
72
73 /** Build a new altitude detector.
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 * <p>The maximal interval between altitude checks should
78 * be smaller than the half duration of the minimal pass to handle,
79 * otherwise some short passes could be missed.</p>
80 * @param maxCheck maximal checking interval (s)
81 * @param threshold convergence threshold (s)
82 * @param altitude threshold altitude value (m)
83 * @param bodyShape body shape with respect to which altitude should be evaluated
84 */
85 public AltitudeDetector(final double maxCheck,
86 final double threshold,
87 final double altitude,
88 final BodyShape bodyShape) {
89 this(maxCheck, threshold, DEFAULT_MAX_ITER, new StopOnDecreasing<AltitudeDetector>(),
90 altitude, bodyShape);
91 }
92
93 /** Private constructor with full parameters.
94 * <p>
95 * This constructor is private as users are expected to use the builder
96 * API with the various {@code withXxx()} methods to set up the instance
97 * in a readable manner without using a huge amount of parameters.
98 * </p>
99 * @param maxCheck maximum checking interval (s)
100 * @param threshold convergence threshold (s)
101 * @param maxIter maximum number of iterations in the event time search
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 6.1
106 */
107 private AltitudeDetector(final double maxCheck, final double threshold,
108 final int maxIter, final EventHandler<? super AltitudeDetector> handler,
109 final double altitude,
110 final BodyShape bodyShape) {
111 super(maxCheck, threshold, maxIter, handler);
112 this.altitude = altitude;
113 this.bodyShape = bodyShape;
114 }
115
116 /** {@inheritDoc} */
117 @Override
118 protected AltitudeDetector create(final double newMaxCheck, final double newThreshold,
119 final int newMaxIter, final EventHandler<? super AltitudeDetector> newHandler) {
120 return new AltitudeDetector(newMaxCheck, newThreshold, newMaxIter, newHandler,
121 altitude, bodyShape);
122 }
123
124 /** Get the threshold altitude value.
125 * @return the threshold altitude value (m)
126 */
127 public double getAltitude() {
128 return altitude;
129 }
130
131 /** Get the body shape.
132 * @return the body shape
133 */
134 public BodyShape getBodyShape() {
135 return bodyShape;
136 }
137
138 /** Compute the value of the switching function.
139 * This function measures the difference between the current altitude
140 * and the threshold altitude.
141 * @param s the current state information: date, kinematics, attitude
142 * @return value of the switching function
143 */
144 public double g(final SpacecraftState s) {
145 final Frame bodyFrame = bodyShape.getBodyFrame();
146 final PVCoordinates pvBody = s.getPVCoordinates(bodyFrame);
147 final GeodeticPoint point = bodyShape.transform(pvBody.getPosition(),
148 bodyFrame, s.getDate());
149 return point.getAltitude() - altitude;
150 }
151
152 }