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.BeforeEach;
22  import org.junit.jupiter.api.Test;
23  import org.orekit.Utils;
24  import org.orekit.bodies.CelestialBodyFactory;
25  import org.orekit.bodies.GeodeticPoint;
26  import org.orekit.bodies.OneAxisEllipsoid;
27  import org.orekit.frames.FramesFactory;
28  import org.orekit.frames.TopocentricFrame;
29  import org.orekit.models.AtmosphericRefractionModel;
30  import org.orekit.models.earth.ITURP834AtmosphericRefraction;
31  import org.orekit.orbits.CircularOrbit;
32  import org.orekit.orbits.PositionAngleType;
33  import org.orekit.propagation.Propagator;
34  import org.orekit.propagation.analytical.KeplerianPropagator;
35  import org.orekit.propagation.events.EventsLogger.LoggedEvent;
36  import org.orekit.time.AbsoluteDate;
37  import org.orekit.time.TimeScale;
38  import org.orekit.time.TimeScalesFactory;
39  import org.orekit.utils.Constants;
40  import org.orekit.utils.IERSConventions;
41  
42  import java.util.List;
43  
44  public class GroundAtNightDetectorTest {
45  
46      @Test
47      public void testMidLatitudeCivilNoRefraction() {
48          checkDuration(FastMath.toRadians(43.0), FastMath.toRadians(0.0),
49                        GroundAtNightDetector.CIVIL_DAWN_DUSK_ELEVATION,
50                        null, 45037.367);
51      }
52  
53      @Test
54      public void testMidLatitudeCivilITURefraction() {
55          checkDuration(FastMath.toRadians(43.0), FastMath.toRadians(0.0),
56                        GroundAtNightDetector.CIVIL_DAWN_DUSK_ELEVATION,
57                        new ITURP834AtmosphericRefraction(0.0), 43909.148);
58      }
59  
60      @Test
61      public void testMidLatitudeNauticalNoRefraction() {
62          checkDuration(FastMath.toRadians(43.0), FastMath.toRadians(0.0),
63                        GroundAtNightDetector.NAUTICAL_DAWN_DUSK_ELEVATION,
64                        null, 41045.750);
65      }
66  
67      @Test
68      public void testMidLatitudeNauticalITURefraction() {
69          checkDuration(FastMath.toRadians(43.0), FastMath.toRadians(0.0),
70                        GroundAtNightDetector.NAUTICAL_DAWN_DUSK_ELEVATION,
71                        new ITURP834AtmosphericRefraction(0.0), 39933.656);
72      }
73  
74      @Test
75      public void testMidLatitudeAstronomicalNoRefraction() {
76          checkDuration(FastMath.toRadians(43.0), FastMath.toRadians(0.0),
77                        GroundAtNightDetector.ASTRONOMICAL_DAWN_DUSK_ELEVATION,
78                        null, 37097.821);
79      }
80  
81      @Test
82      public void testMidLatitudeAstronomicalITURefraction() {
83          checkDuration(FastMath.toRadians(43.0), FastMath.toRadians(0.0),
84                        GroundAtNightDetector.ASTRONOMICAL_DAWN_DUSK_ELEVATION,
85                        new ITURP834AtmosphericRefraction(0.0), 35991.314);
86      }
87  
88      @Test
89      public void testHighLatitudeAstronomicalITURefraction() {
90          checkDuration(FastMath.toRadians(84.0), FastMath.toRadians(0.0),
91                        GroundAtNightDetector.ASTRONOMICAL_DAWN_DUSK_ELEVATION,
92                        new ITURP834AtmosphericRefraction(0.0), Double.NaN);
93      }
94  
95      private void checkDuration(double latitude, double longitude, double dawnDuskElevation,
96                                 AtmosphericRefractionModel refractionModel,
97                                 double expectedDuration) {
98          OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
99                                                        Constants.WGS84_EARTH_FLATTENING,
100                                                       FramesFactory.getITRF(IERSConventions.IERS_2010, true));
101         TimeScale utc = TimeScalesFactory.getUTC();
102         CircularOrbit o = new CircularOrbit(7200000.0, 1.0e-3, 2.0e-4,
103                                             FastMath.toRadians(50.0), FastMath.toRadians(134.0),
104                                             FastMath.toRadians(21.0), PositionAngleType.MEAN, FramesFactory.getGCRF(),
105                                             new AbsoluteDate("2003-02-14T14:02:03.000", utc),
106                                             Constants.EIGEN5C_EARTH_MU);
107 
108         TopocentricFrame topo = new TopocentricFrame(earth, new GeodeticPoint(latitude, longitude, 0.0), "");
109         Propagator p = new KeplerianPropagator(o);
110         EventsLogger logger = new EventsLogger();
111         p.addEventDetector(logger.monitorDetector(new GroundAtNightDetector(topo,
112                                                                             CelestialBodyFactory.getSun(),
113                                                                             dawnDuskElevation, refractionModel).
114                                                   withMaxCheck(120.0)));
115         p.propagate(o.getDate().shiftedBy(Constants.JULIAN_DAY));
116         List<LoggedEvent> events = logger.getLoggedEvents();
117         if (Double.isNaN(expectedDuration)) {
118             Assertions.assertEquals(0, events.size());
119         } else {
120             Assertions.assertEquals(2, events.size());
121             Assertions.assertEquals(expectedDuration,
122                                 events.get(1).getState().getDate().durationFrom(events.get(0).getState().getDate()),
123                                 1.0e-3);
124         }
125 
126     }
127 
128     @BeforeEach
129     public void setUp() {
130         Utils.setDataRoot("regular-data");
131     }
132 
133 }
134