1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.events;
18
19 import org.hipparchus.geometry.euclidean.threed.Line;
20 import org.hipparchus.geometry.euclidean.threed.Vector3D;
21 import org.hipparchus.ode.events.Action;
22 import org.hipparchus.util.FastMath;
23 import org.junit.jupiter.api.Assertions;
24 import org.junit.jupiter.api.BeforeEach;
25 import org.junit.jupiter.api.Test;
26 import org.orekit.Utils;
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.orbits.CircularOrbit;
32 import org.orekit.orbits.PositionAngleType;
33 import org.orekit.propagation.Propagator;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.analytical.KeplerianPropagator;
36 import org.orekit.propagation.events.EventsLogger.LoggedEvent;
37 import org.orekit.propagation.events.handlers.EventHandler;
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.TrackingCoordinates;
44
45 public class InterSatDirectViewDetectorTest {
46
47 @Test
48 public void testFormationFlying() {
49 final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
50 Constants.WGS84_EARTH_FLATTENING,
51 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
52 final TimeScale utc = TimeScalesFactory.getUTC();
53 final CircularOrbit o1 = new CircularOrbit(7200000.0, 1.0e-3, 2.0e-4,
54 FastMath.toRadians(98.7), FastMath.toRadians(134.0),
55 FastMath.toRadians(21.0), PositionAngleType.MEAN, FramesFactory.getGCRF(),
56 new AbsoluteDate("2003-02-14T01:02:03.000", utc),
57 Constants.EIGEN5C_EARTH_MU);
58 final CircularOrbit o2 = new CircularOrbit(o1.getA(), 2.0e-4, 1.0e-3,
59 o1.getI() + 1.0e-6, o1.getRightAscensionOfAscendingNode() - 3.5e-7,
60 o1.getAlphaM() + 2.2e-6, PositionAngleType.MEAN, o1.getFrame(),
61 o1.getDate(),
62 Constants.EIGEN5C_EARTH_MU);
63 Assertions.assertEquals(o1.getKeplerianPeriod(), o2.getKeplerianPeriod(), 1.0e-10);
64 final Propagator p = new KeplerianPropagator(o1);
65 final EventsLogger logger = new EventsLogger();
66 p.addEventDetector(logger.monitorDetector(new InterSatDirectViewDetector(earth, o2).
67 withMaxCheck(60.0)));
68 p.setStepHandler(10.0, state -> {
69 Vector3D pos1 = state.getPosition();
70 Vector3D pos2 = o2.getPosition(state.getDate(), state.getFrame());
71 Assertions.assertTrue(Vector3D.distance(pos1, pos2) > 8100.0);
72 Assertions.assertTrue(Vector3D.distance(pos1, pos2) < 16400.0);
73 });
74 p.propagate(o1.getDate().shiftedBy(o1.getKeplerianPeriod()));
75 Assertions.assertEquals(0, logger.getLoggedEvents().size());
76 }
77
78 @Test
79 public void testLeoMeo() {
80 OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
81 Constants.WGS84_EARTH_FLATTENING,
82 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
83 TimeScale utc = TimeScalesFactory.getUTC();
84 CircularOrbit o1 = new CircularOrbit(7200000.0, 1.0e-3, 2.0e-4,
85 FastMath.toRadians(50.0), FastMath.toRadians(134.0),
86 FastMath.toRadians(21.0), PositionAngleType.MEAN, FramesFactory.getGCRF(),
87 new AbsoluteDate("2003-02-14T01:02:03.000", utc),
88 Constants.EIGEN5C_EARTH_MU);
89 final CircularOrbit o2 = new CircularOrbit(29600000.0, 2.0e-4, 1.0e-3,
90 FastMath.toRadians(56.0), FastMath.toRadians(111.0),
91 o1.getAlphaM() + 2.2e-6, PositionAngleType.MEAN, o1.getFrame(),
92 o1.getDate(),
93 Constants.EIGEN5C_EARTH_MU);
94
95
96 Propagator pA = new KeplerianPropagator(o1);
97 EventsLogger loggerA = new EventsLogger();
98 pA.addEventDetector(loggerA.monitorDetector(new InterSatDirectViewDetector(earth, o2).
99 withMaxCheck(10.0).
100 withHandler(new GrazingHandler())));
101 pA.propagate(o1.getDate().shiftedBy(4 * o1.getKeplerianPeriod()));
102 Assertions.assertEquals(7, loggerA.getLoggedEvents().size());
103
104
105 Propagator pB = new KeplerianPropagator(o2);
106 EventsLogger loggerB = new EventsLogger();
107 pB.addEventDetector(loggerB.monitorDetector(new InterSatDirectViewDetector(earth, o1).
108 withMaxCheck(10.0).
109 withHandler(new GrazingHandler())));
110 pB.propagate(o1.getDate().shiftedBy(4 * o1.getKeplerianPeriod()));
111 Assertions.assertEquals(7, loggerB.getLoggedEvents().size());
112
113 }
114
115 @Test
116 public void testSkimmingAltitude() {
117 OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
118 Constants.WGS84_EARTH_FLATTENING,
119 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
120 TimeScale utc = TimeScalesFactory.getUTC();
121 CircularOrbit o1 = new CircularOrbit(7200000.0, 1.0e-3, 2.0e-4,
122 FastMath.toRadians(50.0), FastMath.toRadians(134.0),
123 FastMath.toRadians(21.0), PositionAngleType.MEAN, FramesFactory.getGCRF(),
124 new AbsoluteDate("2003-02-14T01:02:03.000", utc),
125 Constants.EIGEN5C_EARTH_MU);
126 final CircularOrbit o2 = new CircularOrbit(29600000.0, 2.0e-4, 1.0e-3,
127 FastMath.toRadians(56.0), FastMath.toRadians(111.0),
128 o1.getAlphaM() + 2.2e-6, PositionAngleType.MEAN, o1.getFrame(),
129 o1.getDate(),
130 Constants.EIGEN5C_EARTH_MU);
131
132
133 Propagator pA = new KeplerianPropagator(o1);
134 EventsLogger loggerA = new EventsLogger();
135 pA.addEventDetector(loggerA.monitorDetector(new InterSatDirectViewDetector(earth, o2).
136 withMaxCheck(10.0)));
137 pA.propagate(o1.getDate().shiftedBy(4 * o1.getKeplerianPeriod()));
138 Assertions.assertEquals(7, loggerA.getLoggedEvents().size());
139
140
141 Propagator pB = new KeplerianPropagator(o2);
142 EventsLogger loggerB = new EventsLogger();
143 pB.addEventDetector(loggerB.monitorDetector(new InterSatDirectViewDetector(earth, o1).
144 withMaxCheck(10.0).
145 withSkimmingAltitude(500000.0)));
146 pB.propagate(o1.getDate().shiftedBy(4 * o1.getKeplerianPeriod()));
147 Assertions.assertEquals(7, loggerB.getLoggedEvents().size());
148
149 for (int i = 0; i < loggerA.getLoggedEvents().size(); ++i) {
150 final LoggedEvent leA = loggerA.getLoggedEvents().get(i);
151 final LoggedEvent leB = loggerB.getLoggedEvents().get(i);
152 if (leA.isIncreasing()) {
153
154
155 Assertions.assertTrue(leA.getDate().isBefore(leB));
156 } else {
157
158
159 Assertions.assertTrue(leB.getDate().isBefore(leA));
160 }
161 }
162
163 }
164
165 private static class GrazingHandler implements EventHandler {
166 public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
167
168
169 final InterSatDirectViewDetector isdv = (InterSatDirectViewDetector) detector;
170 final OneAxisEllipsoid earth = isdv.getCentralBody();
171 final Frame frame = earth.getBodyFrame();
172 final double dt = increasing ? -1.0e-8 : +1.0e-8;
173 final AbsoluteDate grazingDate = s.getDate().shiftedBy(dt);
174 final Vector3D pPrimary = s.shiftedBy(dt).getPosition(frame);
175 final Vector3D psecondary = isdv.getSecondary().getPosition(grazingDate, frame);
176 final Vector3D grazing = earth.getCartesianIntersectionPoint(new Line(pPrimary, psecondary, 1.0),
177 pPrimary, frame, grazingDate);
178 final TopocentricFrame topo = new TopocentricFrame(earth, earth.transform(grazing, frame, grazingDate),
179 "grazing");
180 final TrackingCoordinates tcPrimary = topo.getTrackingCoordinates(pPrimary, frame, grazingDate);
181 final TrackingCoordinates tcSecondary = topo.getTrackingCoordinates(psecondary, frame, grazingDate);
182 Assertions.assertEquals( 0.0, FastMath.toDegrees(tcPrimary.getElevation()), 2.0e-4);
183 Assertions.assertEquals( 0.0, FastMath.toDegrees(tcSecondary.getElevation()), 2.0e-4);
184 Assertions.assertEquals(180.0,
185 FastMath.abs(FastMath.toDegrees(tcSecondary.getAzimuth() - tcPrimary.getAzimuth())),
186 6.0e-14);
187 return Action.CONTINUE;
188 }
189 }
190
191 @BeforeEach
192 public void setUp() {
193 Utils.setDataRoot("regular-data");
194 }
195
196 }
197