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.util.FastMath;
20  import org.junit.jupiter.api.Assertions;
21  import org.junit.jupiter.api.Test;
22  import org.mockito.Mockito;
23  import org.orekit.Utils;
24  import org.orekit.bodies.CelestialBodyFactory;
25  import org.orekit.frames.Frame;
26  import org.orekit.frames.FramesFactory;
27  import org.orekit.orbits.KeplerianOrbit;
28  import org.orekit.orbits.Orbit;
29  import org.orekit.orbits.PositionAngleType;
30  import org.orekit.propagation.Propagator;
31  import org.orekit.propagation.SpacecraftState;
32  import org.orekit.propagation.analytical.KeplerianPropagator;
33  import org.orekit.propagation.events.handlers.StopOnEvent;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.utils.PVCoordinatesProvider;
36  
37  public class ExtremumApproachDetectorTest {
38  
39      /**
40      * Test the detector on a keplerian orbit and detect extremum approach with Earth.
41      */
42      @Test
43      public void testStopPropagationClosestApproachByDefault() {
44          // Given
45          // Loading Orekit data
46          Utils.setDataRoot("regular-data");
47  
48          // Generating orbit
49          final AbsoluteDate initialDate = new AbsoluteDate();
50          final Frame frame = FramesFactory.getEME2000();
51          final double mu = 398600e9; //m**3/s**2
52  
53          final double rp = (6378 + 400) * 1000; //m
54          final double ra = (6378 + 800) * 1000; //m
55  
56          final double a = (ra + rp) / 2; //m
57          final double e = (ra - rp) / (ra + rp); //m
58          final double i = 0; //rad
59          final double pa = 0; //rad
60          final double raan = 0; //rad
61          final double anomaly = FastMath.toRadians(0); //rad
62          final Orbit orbit =
63                  new KeplerianOrbit(a, e, i, pa, raan, anomaly, PositionAngleType.TRUE, frame, initialDate, mu);
64  
65          // Will detect extremum approaches with Earth
66          final PVCoordinatesProvider earthPVProvider = CelestialBodyFactory.getEarth();
67  
68          // Initializing detector
69          final ExtremumApproachDetector detector = new ExtremumApproachDetector(earthPVProvider);
70  
71          // Initializing propagator
72          final Propagator propagator = new KeplerianPropagator(orbit);
73          propagator.addEventDetector(detector);
74  
75          // When
76          final SpacecraftState stateAtEvent =
77                  propagator.propagate(initialDate.shiftedBy(orbit.getKeplerianPeriod() * 2));
78  
79          // Then
80          Assertions.assertEquals(stateAtEvent.getDate().durationFrom(initialDate),orbit.getKeplerianPeriod(),1e-9);
81  
82      }
83  
84      /**
85      * Test the detector on a keplerian orbit and detect extremum approach with Earth.
86      */
87      @Test
88      public void testStopPropagationFarthestApproachWithHandler() {
89          
90          // Given
91          // Loading Orekit data
92          Utils.setDataRoot("regular-data");
93  
94          // Generating orbit
95          final AbsoluteDate initialDate = new AbsoluteDate();
96          final Frame frame = FramesFactory.getEME2000();
97          final double mu = 398600e9; //m**3/s**2
98  
99          final double rp = (6378 + 400) * 1000; //m
100         final double ra = (6378 + 800) * 1000; //m
101 
102         final double a = (ra + rp) / 2; //m
103         final double e = (ra - rp) / (ra + rp); //m
104         final double i = 0; //rad
105         final double pa = 0; //rad
106         final double raan = 0; //rad
107         final double anomaly = FastMath.toRadians(0); //rad
108         final Orbit orbit =
109                 new KeplerianOrbit(a, e, i, pa, raan, anomaly, PositionAngleType.TRUE, frame, initialDate, mu);
110 
111         // Will detect extremum approaches with Earth
112         final PVCoordinatesProvider earthPVProvider = CelestialBodyFactory.getEarth();
113 
114         // Initializing detector with custom handler
115         final ExtremumApproachDetector detector =
116                 new ExtremumApproachDetector(earthPVProvider).withHandler(new StopOnEvent());
117 
118         // Initializing propagator
119         final Propagator propagator = new KeplerianPropagator(orbit);
120         propagator.addEventDetector(detector);
121 
122         // When
123         final SpacecraftState stateAtEvent =
124                 propagator.propagate(initialDate.shiftedBy(orbit.getKeplerianPeriod() * 2));
125 
126         // Then
127         Assertions.assertEquals(stateAtEvent.getDate().durationFrom(initialDate),orbit.getKeplerianPeriod() / 2,1e-7);
128 
129     }
130 
131     @Test
132     void testSecondaryPVCoordinatesProviderGetter() {
133         // Given
134         final PVCoordinatesProvider    secondaryPVProvider      = Mockito.mock(PVCoordinatesProvider.class);
135         final ExtremumApproachDetector extremumApproachDetector = new ExtremumApproachDetector(secondaryPVProvider);
136 
137         // When
138         final PVCoordinatesProvider returnedSecondaryPVProvider = extremumApproachDetector.getSecondaryPVProvider();
139 
140         // Then
141         Assertions.assertEquals(secondaryPVProvider, returnedSecondaryPVProvider);
142     }
143 }