1   /* Copyright 2002-2022 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.geometry.euclidean.threed.Vector3D;
20  import org.hipparchus.util.FastMath;
21  import org.junit.Assert;
22  import org.junit.Before;
23  import org.junit.Test;
24  import org.orekit.Utils;
25  import org.orekit.bodies.GeodeticPoint;
26  import org.orekit.bodies.OneAxisEllipsoid;
27  import org.orekit.frames.FramesFactory;
28  import org.orekit.orbits.EquinoctialOrbit;
29  import org.orekit.orbits.KeplerianOrbit;
30  import org.orekit.orbits.Orbit;
31  import org.orekit.orbits.PositionAngle;
32  import org.orekit.propagation.Propagator;
33  import org.orekit.propagation.SpacecraftState;
34  import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
35  import org.orekit.propagation.analytical.KeplerianPropagator;
36  import org.orekit.propagation.events.EventsLogger.LoggedEvent;
37  import org.orekit.propagation.events.handlers.ContinueOnEvent;
38  import org.orekit.time.AbsoluteDate;
39  import org.orekit.time.TimeScale;
40  import org.orekit.time.TimeScalesFactory;
41  import org.orekit.utils.Constants;
42  import org.orekit.utils.IERSConventions;
43  import org.orekit.utils.PVCoordinates;
44  
45  public class LongitudeCrossingDetectorTest {
46  
47      @Test
48      public void testRegularCrossing() {
49  
50          final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
51                                                              Constants.WGS84_EARTH_FLATTENING,
52                                                              FramesFactory.getITRF(IERSConventions.IERS_2010, true));
53  
54          LongitudeCrossingDetector d =
55                  new LongitudeCrossingDetector(earth, FastMath.toRadians(10.0)).
56                  withMaxCheck(60).
57                  withThreshold(1.e-6).
58                  withHandler(new ContinueOnEvent<LongitudeCrossingDetector>());
59  
60          Assert.assertEquals(60.0, d.getMaxCheckInterval(), 1.0e-15);
61          Assert.assertEquals(1.0e-6, d.getThreshold(), 1.0e-15);
62          Assert.assertEquals(10.0, FastMath.toDegrees(d.getLongitude()), 1.0e-14);
63          Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, d.getMaxIterationCount());
64          Assert.assertSame(earth, d.getBody());
65  
66          final TimeScale utc = TimeScalesFactory.getUTC();
67          final Vector3D position = new Vector3D(-6142438.668, 3492467.56, -25767.257);
68          final Vector3D velocity = new Vector3D(505.848, 942.781, 7435.922);
69          final AbsoluteDate date = new AbsoluteDate(2003, 9, 16, utc);
70          final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position,  velocity),
71                                                   FramesFactory.getEME2000(), date,
72                                                   Constants.EIGEN5C_EARTH_MU);
73  
74          Propagator propagator =
75              new EcksteinHechlerPropagator(orbit,
76                                            Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
77                                            Constants.EIGEN5C_EARTH_MU,
78                                            Constants.EIGEN5C_EARTH_C20,
79                                            Constants.EIGEN5C_EARTH_C30,
80                                            Constants.EIGEN5C_EARTH_C40,
81                                            Constants.EIGEN5C_EARTH_C50,
82                                            Constants.EIGEN5C_EARTH_C60);
83  
84          EventsLogger logger = new EventsLogger();
85          propagator.addEventDetector(logger.monitorDetector(d));
86  
87          propagator.propagate(date.shiftedBy(Constants.JULIAN_DAY));
88          AbsoluteDate previous = null;
89          for (LoggedEvent e : logger.getLoggedEvents()) {
90              SpacecraftState state = e.getState();
91              double longitude = earth.transform(state.getPVCoordinates(earth.getBodyFrame()).getPosition(),
92                                                earth.getBodyFrame(), null).getLongitude();
93              Assert.assertEquals(10.0, FastMath.toDegrees(longitude), 1.6e-7);
94              if (previous != null) {
95                  // same time interval regardless of increasing/decreasing,
96                  // as increasing/decreasing flag is irrelevant for this detector
97                   Assert.assertEquals(4954.70, state.getDate().durationFrom(previous), 1e10);
98              }
99              previous = state.getDate();
100         }
101         Assert.assertEquals(16, logger.getLoggedEvents().size());
102 
103     }
104 
105     @Test
106     public void testZigZag() {
107 
108         final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
109                                                             Constants.WGS84_EARTH_FLATTENING,
110                                                             FramesFactory.getITRF(IERSConventions.IERS_2010, true));
111 
112         LongitudeCrossingDetector d =
113                 new LongitudeCrossingDetector(600.0, 1.e-6, earth, FastMath.toRadians(-100.0)).
114                 withHandler(new ContinueOnEvent<LongitudeCrossingDetector>());
115 
116         Assert.assertEquals(600.0, d.getMaxCheckInterval(), 1.0e-15);
117         Assert.assertEquals(1.0e-6, d.getThreshold(), 1.0e-15);
118         Assert.assertEquals(-100.0, FastMath.toDegrees(d.getLongitude()), 1.0e-14);
119         Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, d.getMaxIterationCount());
120 
121         KeplerianOrbit orbit =
122                         new KeplerianOrbit(24464560.0, 0.7311, 0.122138, 3.10686, 1.00681,
123                                            0.048363, PositionAngle.MEAN,
124                                            FramesFactory.getEME2000(),
125                                            AbsoluteDate.J2000_EPOCH,
126                                            Constants.EIGEN5C_EARTH_MU);
127 
128 
129         Propagator propagator = new KeplerianPropagator(orbit);
130 
131         EventsLogger logger = new EventsLogger();
132         propagator.addEventDetector(logger.monitorDetector(d));
133 
134         propagator.propagate(orbit.getDate().shiftedBy(Constants.JULIAN_DAY));
135         double[] expectedLatitudes = new double[] { -6.5394381901, -0.4918760372, +6.5916016832 };
136         Assert.assertEquals(3, logger.getLoggedEvents().size());
137         for (int i = 0; i < 3; ++i) {
138             SpacecraftState state = logger.getLoggedEvents().get(i).getState();
139             GeodeticPoint gp = earth.transform(state.getPVCoordinates(earth.getBodyFrame()).getPosition(),
140                                                earth.getBodyFrame(), null);
141             Assert.assertEquals(expectedLatitudes[i], FastMath.toDegrees(gp.getLatitude()),  1.0e-10);
142             Assert.assertEquals(-100.0,               FastMath.toDegrees(gp.getLongitude()), 1.2e-9);
143         }
144 
145     }
146 
147     @Before
148     public void setUp() {
149         Utils.setDataRoot("regular-data");
150     }
151 
152 }
153