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.ode.events.Action;
20  import org.hipparchus.util.FastMath;
21  import org.junit.jupiter.api.AfterEach;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.BeforeEach;
24  import org.junit.jupiter.api.Test;
25  import org.orekit.Utils;
26  import org.orekit.bodies.CelestialBodyFactory;
27  import org.orekit.bodies.GeodeticPoint;
28  import org.orekit.bodies.OneAxisEllipsoid;
29  import org.orekit.errors.OrekitException;
30  import org.orekit.frames.FramesFactory;
31  import org.orekit.frames.TopocentricFrame;
32  import org.orekit.orbits.KeplerianOrbit;
33  import org.orekit.orbits.Orbit;
34  import org.orekit.orbits.PositionAngleType;
35  import org.orekit.propagation.Propagator;
36  import org.orekit.propagation.SpacecraftState;
37  import org.orekit.propagation.analytical.KeplerianPropagator;
38  import org.orekit.propagation.events.handlers.EventHandler;
39  import org.orekit.time.AbsoluteDate;
40  import org.orekit.time.TimeScalesFactory;
41  import org.orekit.utils.Constants;
42  import org.orekit.utils.IERSConventions;
43  import org.orekit.utils.PVCoordinatesProvider;
44  
45  public class AngularSeparationDetectorTest {
46  
47      private OneAxisEllipsoid earth;
48      private TopocentricFrame acatenango;
49      private AbsoluteDate     iniDate;
50      private Orbit            initialOrbit;
51      private Propagator       propagator;
52  
53      @Test
54      public void testCentralSunTransit() {
55  
56          double proximityAngle = FastMath.toRadians(0.1);
57          double maxCheck = 0.1 * proximityAngle / initialOrbit.getKeplerianMeanMotion();
58          PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
59          AngularSeparationDetector detector =
60              new AngularSeparationDetector(sun, acatenango, proximityAngle).
61              withMaxCheck(maxCheck).
62              withThreshold(1.0e-6);
63          Assertions.assertEquals(proximityAngle, detector.getProximityAngle(), 1.0e-15);
64          Assertions.assertSame(sun,    detector.getBeacon());
65          Assertions.assertSame(acatenango,  detector.getObserver());
66          Assertions.assertEquals(maxCheck, detector.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
67          propagator.addEventDetector(detector);
68          final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(7000.0));
69          Assertions.assertEquals(1921.1311, finalState.getDate().durationFrom(iniDate), 1.0e-3);
70  
71      }
72  
73      @Test
74      public void testRegularProximity() {
75  
76          double proximityAngle = FastMath.toRadians(5.0);
77          double maxCheck = 0.1 * proximityAngle / initialOrbit.getKeplerianMeanMotion();
78          PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
79          AngularSeparationDetector detector =
80              new AngularSeparationDetector(sun, acatenango, proximityAngle).
81              withMaxCheck(maxCheck).
82              withThreshold(1.0e-6).
83              withHandler(new EventHandler() {
84                  public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
85                      if (increasing) {
86                          Assertions.assertEquals(1928.3659, s.getDate().durationFrom(iniDate), 1.0e-3);
87                      } else {
88                          Assertions.assertEquals(1914.1680, s.getDate().durationFrom(iniDate), 1.0e-3);
89                      }
90                      return Action.CONTINUE;
91                  }
92              });
93          Assertions.assertEquals(proximityAngle, detector.getProximityAngle(), 1.0e-15);
94          Assertions.assertSame(sun,    detector.getBeacon());
95          Assertions.assertSame(acatenango,  detector.getObserver());
96          Assertions.assertEquals(maxCheck, detector.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
97          propagator.addEventDetector(detector);
98          final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(7000.0));
99          Assertions.assertEquals(7000.0, finalState.getDate().durationFrom(iniDate), 1.0e-3);
100 
101     }
102 
103     @BeforeEach
104     public void setUp() {
105         try {
106             Utils.setDataRoot("regular-data");
107             earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
108                                          Constants.WGS84_EARTH_FLATTENING,
109                                          FramesFactory.getITRF(IERSConventions.IERS_2010, true));
110             acatenango = new TopocentricFrame(earth,
111                                               new GeodeticPoint(FastMath.toRadians(14.500833),
112                                                                 FastMath.toRadians(-90.87583),
113                                                                 3976.0),
114                                               "Acatenango");
115             iniDate = new AbsoluteDate(2003, 5, 1, 17, 30, 0.0, TimeScalesFactory.getUTC());
116             initialOrbit = new KeplerianOrbit(7e6, 1.0e-4, FastMath.toRadians(98.5),
117                                               FastMath.toRadians(87.0), FastMath.toRadians(216.59976025619),
118                                               FastMath.toRadians(319.7), PositionAngleType.MEAN,
119                                               FramesFactory.getEME2000(), iniDate,
120                                               Constants.EIGEN5C_EARTH_MU);
121             propagator = new KeplerianPropagator(initialOrbit);
122         } catch (OrekitException oe) {
123             Assertions.fail(oe.getLocalizedMessage());
124         }
125     }
126 
127     @AfterEach
128     public void tearDown() {
129         earth        = null;
130         iniDate      = null;
131         initialOrbit = null;
132         propagator   = null;
133     }
134 
135 }
136