1   package org.orekit.propagation.events;
2   
3   import org.hipparchus.geometry.euclidean.threed.Vector3D;
4   import org.hipparchus.ode.events.Action;
5   import org.hipparchus.util.FastMath;
6   import org.junit.After;
7   import org.junit.Assert;
8   import org.junit.Before;
9   import org.junit.Test;
10  import org.orekit.Utils;
11  import org.orekit.bodies.CelestialBodyFactory;
12  import org.orekit.bodies.GeodeticPoint;
13  import org.orekit.bodies.OneAxisEllipsoid;
14  import org.orekit.errors.OrekitException;
15  import org.orekit.frames.FramesFactory;
16  import org.orekit.frames.TopocentricFrame;
17  import org.orekit.orbits.KeplerianOrbit;
18  import org.orekit.orbits.Orbit;
19  import org.orekit.orbits.PositionAngle;
20  import org.orekit.propagation.Propagator;
21  import org.orekit.propagation.SpacecraftState;
22  import org.orekit.propagation.analytical.KeplerianPropagator;
23  import org.orekit.propagation.events.handlers.EventHandler;
24  import org.orekit.time.AbsoluteDate;
25  import org.orekit.time.TimeScalesFactory;
26  import org.orekit.utils.Constants;
27  import org.orekit.utils.IERSConventions;
28  import org.orekit.utils.PVCoordinates;
29  import org.orekit.utils.PVCoordinatesProvider;
30  
31  public class AngularSeparationFromSatelliteDetectorTest {
32  
33      private OneAxisEllipsoid earth;
34      private TopocentricFrame acatenango;
35      private AbsoluteDate     iniDate;
36      private Orbit            initialOrbit;
37      private Propagator       propagator;
38  
39      @Test
40      public void testCentralSunTransit() {
41  
42          double proximityAngle = FastMath.toRadians(10.0);
43          double maxCheck = 0.1 * proximityAngle / initialOrbit.getKeplerianMeanMotion();
44          PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
45          AngularSeparationFromSatelliteDetector detector =
46                          new AngularSeparationFromSatelliteDetector(sun, acatenango, proximityAngle).
47                          withMaxCheck(maxCheck).
48                          withThreshold(1.0e-6);
49          Assert.assertEquals(proximityAngle, detector.getProximityAngle(), 1.0e-15);
50          Assert.assertSame(sun,    detector.getPrimaryObject());
51          Assert.assertSame(acatenango,  detector.getSecondaryObject());
52          Assert.assertEquals(maxCheck, detector.getMaxCheckInterval(), 1.0e-15);
53          propagator.addEventDetector(detector);
54          final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(3600 * 2));
55          Assert.assertEquals(4587.6472, finalState.getDate().durationFrom(iniDate), 1.0e-3);
56          
57          final PVCoordinates sPV = finalState.getPVCoordinates();
58          final PVCoordinates primaryPV   = sun       .getPVCoordinates(finalState.getDate(), finalState.getFrame());
59          final PVCoordinates secondaryPV = acatenango.getPVCoordinates(finalState.getDate(), finalState.getFrame());
60          final double separation = Vector3D.angle(primaryPV  .getPosition().subtract(sPV.getPosition()),
61                                                   secondaryPV.getPosition().subtract(sPV.getPosition()));
62          Assert.assertTrue(separation < proximityAngle);
63  
64      }
65  
66      @Test
67      public void testRegularProximity() {
68  
69          double proximityAngle = FastMath.toRadians(15.0);
70          double maxCheck = 0.1 * proximityAngle / initialOrbit.getKeplerianMeanMotion();
71          PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
72          AngularSeparationFromSatelliteDetector detector =
73                          new AngularSeparationFromSatelliteDetector(sun, acatenango, proximityAngle).
74                          withMaxCheck(maxCheck).
75                          withThreshold(1.0e-6).
76                          withHandler(new EventHandler<AngularSeparationFromSatelliteDetector>() {
77                  public Action eventOccurred(SpacecraftState s, AngularSeparationFromSatelliteDetector detector, boolean increasing) {
78                      if (increasing) {
79                          Assert.assertEquals(5259.6649, s.getDate().durationFrom(iniDate), 1.0e-3);
80                      } else {
81                          Assert.assertEquals(4410.2581, s.getDate().durationFrom(iniDate), 1.0e-3);
82                      }
83                      return Action.CONTINUE;
84                  }
85              });
86          Assert.assertEquals(proximityAngle, detector.getProximityAngle(), 1.0e-15);
87          Assert.assertSame(sun,    detector.getPrimaryObject());
88          Assert.assertSame(acatenango,  detector.getSecondaryObject());
89          Assert.assertEquals(maxCheck, detector.getMaxCheckInterval(), 1.0e-15);
90          propagator.addEventDetector(detector);
91          final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(3600 * 2));
92          Assert.assertEquals(7200.0, finalState.getDate().durationFrom(iniDate), 1.0e-3);
93  
94      }
95  
96      @Before
97      public void setUp() {
98          try {
99              Utils.setDataRoot("regular-data");
100             earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
101                                          Constants.WGS84_EARTH_FLATTENING,
102                                          FramesFactory.getITRF(IERSConventions.IERS_2010, true));
103             acatenango = new TopocentricFrame(earth,
104                                               new GeodeticPoint(FastMath.toRadians(14.500833),
105                                                                 FastMath.toRadians(-90.87583),
106                                                                 3976.0),
107                                               "Acatenango");
108             iniDate = new AbsoluteDate(2003, 5, 1, 17, 30, 0.0, TimeScalesFactory.getUTC());
109             initialOrbit = new KeplerianOrbit(7e6, 1.0e-4, FastMath.toRadians(98.5),
110                                               FastMath.toRadians(87.0), FastMath.toRadians(216.59976025619),
111                                               FastMath.toRadians(319.7), PositionAngle.MEAN,
112                                               FramesFactory.getEME2000(), iniDate,
113                                               Constants.EIGEN5C_EARTH_MU);
114             propagator = new KeplerianPropagator(initialOrbit);
115         } catch (OrekitException oe) {
116             Assert.fail(oe.getLocalizedMessage());
117         }
118     }
119 
120     @After
121     public void tearDown() {
122         earth        = null;
123         iniDate      = null;
124         initialOrbit = null;
125         propagator   = null;
126     }
127 }