1   /* Contributed in the public domain.
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.jupiter.api.Assertions;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.junit.jupiter.api.Test;
24  import org.orekit.Utils;
25  import org.orekit.bodies.BodyShape;
26  import org.orekit.bodies.GeodeticPoint;
27  import org.orekit.bodies.OneAxisEllipsoid;
28  import org.orekit.frames.Frame;
29  import org.orekit.frames.FramesFactory;
30  import org.orekit.frames.TopocentricFrame;
31  import org.orekit.geometry.fov.FieldOfView;
32  import org.orekit.geometry.fov.PolygonalFieldOfView;
33  import org.orekit.geometry.fov.PolygonalFieldOfView.DefiningConeType;
34  import org.orekit.orbits.KeplerianOrbit;
35  import org.orekit.orbits.PositionAngleType;
36  import org.orekit.propagation.Propagator;
37  import org.orekit.propagation.analytical.KeplerianPropagator;
38  import org.orekit.propagation.events.EventsLogger.LoggedEvent;
39  import org.orekit.time.AbsoluteDate;
40  import org.orekit.utils.Constants;
41  import org.orekit.utils.IERSConventions;
42  
43  import java.util.List;
44  
45  /**
46   * Unit tests for {@link GroundFieldOfViewDetector}.
47   *
48   * @author Evan Ward
49   */
50  public class GroundFieldOfViewDetectorTest {
51  
52      @BeforeEach
53      public void setUp() {
54          Utils.setDataRoot("regular-data");
55      }
56  
57      /**
58       * Check FoV detector is similar to {@link ElevationDetector} when using
59       * zenith pointing.
60       */
61      @Test
62      public void testCaseSimilarToElevationDetector() {
63          //setup
64          double pi = FastMath.PI;
65          AbsoluteDate date = AbsoluteDate.J2000_EPOCH; //arbitrary date
66          AbsoluteDate endDate = date.shiftedBy(Constants.JULIAN_DAY);
67          Frame eci = FramesFactory.getGCRF();
68          Frame ecef = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
69          BodyShape earth = new OneAxisEllipsoid(
70                  Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
71                  Constants.WGS84_EARTH_FLATTENING,
72                  ecef);
73          GeodeticPoint gp = new GeodeticPoint(
74                  FastMath.toRadians(39), FastMath.toRadians(77), 0);
75          TopocentricFrame topo = new TopocentricFrame(earth, gp, "topo");
76          //iss like orbit
77          KeplerianOrbit orbit = new KeplerianOrbit(
78                  6378137 + 400e3, 0, FastMath.toRadians(51.65), 0, 0, 0,
79                  PositionAngleType.TRUE, eci, date, Constants.EGM96_EARTH_MU);
80          Propagator prop = new KeplerianPropagator(orbit);
81  
82          //compute expected result
83          ElevationDetector elevationDetector =
84                  new ElevationDetector(topo).withConstantElevation(pi / 6)
85                          .withMaxCheck(5.0);
86          EventsLogger logger = new EventsLogger();
87          prop.addEventDetector(logger.monitorDetector(elevationDetector));
88          prop.propagate(endDate);
89          List<LoggedEvent> expected = logger.getLoggedEvents();
90  
91          //action
92          //construct similar FoV based detector
93          //half width of 60 deg pointed along +Z in antenna frame
94          //not a perfect small circle b/c FoV makes a polygon with great circles
95          FieldOfView fov =
96                  new PolygonalFieldOfView(Vector3D.PLUS_K,
97                                           DefiningConeType.INSIDE_CONE_TOUCHING_POLYGON_AT_EDGES_MIDDLE,
98                                           Vector3D.PLUS_I, pi / 3, 16, 0);
99          //simple case for fixed pointing to be similar to elevation detector.
100         //could define new frame with varying rotation for slewing antenna.
101         GroundFieldOfViewDetector fovDetector =
102                 new GroundFieldOfViewDetector(topo, fov)
103                         .withMaxCheck(5.0);
104         Assertions.assertSame(topo, fovDetector.getFrame());
105         Assertions.assertSame(fov, fovDetector.getFOV());
106         logger = new EventsLogger();
107 
108         prop = new KeplerianPropagator(orbit);
109         prop.addEventDetector(logger.monitorDetector(fovDetector));
110         prop.propagate(endDate);
111         List<LoggedEvent> actual = logger.getLoggedEvents();
112 
113         //verify
114         Assertions.assertEquals(2, expected.size());
115         Assertions.assertEquals(2, actual.size());
116         for (int i = 0; i < 2; i++) {
117             AbsoluteDate expectedDate = expected.get(i).getState().getDate();
118             AbsoluteDate actualDate = actual.get(i).getState().getDate();
119             // same event times to within 1s.
120             Assertions.assertEquals(expectedDate.durationFrom(actualDate), 0.0, 1.0);
121         }
122 
123     }
124 
125 }