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.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.ode.events.Action;
22 import org.orekit.orbits.FieldOrbit;
23 import org.orekit.propagation.FieldSpacecraftState;
24 import org.orekit.propagation.events.handlers.FieldEventHandler;
25 import org.orekit.propagation.events.handlers.FieldStopOnIncreasing;
26 import org.orekit.utils.FieldPVCoordinates;
27
28 /** Finder for apside crossing events.
29 * <p>This class finds apside crossing events (i.e. apogee or perigee crossing).</p>
30 * <p>The default implementation behavior is to {@link Action#CONTINUE continue}
31 * propagation at apogee crossing and to {@link Action#STOP stop} propagation
32 * at perigee crossing. This can be changed by calling
33 * {@link #withHandler(FieldEventHandler)} after construction.</p>
34 * <p>Beware that apside detection will fail for almost circular orbits. If
35 * for example an apside detector is used to trigger an {@link
36 * org.orekit.forces.maneuvers.ImpulseManeuver ImpulseManeuver} and the maneuver
37 * change the orbit shape to circular, then the detector may completely fail just
38 * after the maneuver has been performed!</p>
39 * @see org.orekit.propagation.FieldPropagator#addEventDetector(FieldEventDetector)
40 * @author Luc Maisonobe
41 */
42 public class FieldApsideDetector<T extends CalculusFieldElement<T>> extends FieldAbstractDetector<FieldApsideDetector<T>, T> {
43
44 /** Build a new instance.
45 * <p>The orbit is used only to set an upper bound for the
46 * max check interval to period/3 and to set the convergence
47 * threshold according to orbit size</p>
48 * @param orbit initial orbit
49 */
50 public FieldApsideDetector(final FieldOrbit<T> orbit) {
51 this(orbit.getKeplerianPeriod().multiply(1.0e-13), orbit);
52 }
53
54 /** Build a new instance.
55 * <p>The orbit is used only to set an upper bound for the
56 * max check interval to period/3</p>
57 * @param threshold convergence threshold (s)
58 * @param orbit initial orbit
59 */
60 public FieldApsideDetector(final T threshold, final FieldOrbit<T> orbit) {
61 super(orbit.getKeplerianPeriod().divide(3), threshold,
62 DEFAULT_MAX_ITER, new FieldStopOnIncreasing<FieldApsideDetector<T>, T>());
63 }
64
65 /** Private constructor with full parameters.
66 * <p>
67 * This constructor is private as users are expected to use the builder
68 * API with the various {@code withXxx()} methods to set up the instance
69 * in a readable manner without using a huge amount of parameters.
70 * </p>
71 * @param maxCheck maximum checking interval (s)
72 * @param threshold convergence threshold (s)
73 * @param maxIter maximum number of iterations in the event time search
74 * @param handler event handler to call at event occurrences
75 */
76 private FieldApsideDetector(final T maxCheck, final T threshold,
77 final int maxIter, final FieldEventHandler<? super FieldApsideDetector<T>, T> handler) {
78 super(maxCheck, threshold, maxIter, handler);
79 }
80
81 /** {@inheritDoc} */
82 @Override
83 protected FieldApsideDetector<T> create(final T newMaxCheck, final T newThreshold,
84 final int newMaxIter,
85 final FieldEventHandler<? super FieldApsideDetector<T>, T> newHandler) {
86 return new FieldApsideDetector<>(newMaxCheck, newThreshold, newMaxIter, newHandler);
87 }
88
89 /** Compute the value of the switching function.
90 * This function computes the dot product of the 2 vectors : position.velocity.
91 * @param s the current state information: date, kinematics, attitude
92 * @return value of the switching function
93 */
94 public T g(final FieldSpacecraftState<T> s) {
95 final FieldPVCoordinates<T> pv = s.getPVCoordinates();
96 return FieldVector3D.dotProduct(pv.getPosition(), pv.getVelocity());
97 }
98
99 }