1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.geometry.fov;
18
19 import java.util.List;
20
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.random.RandomGenerator;
23 import org.hipparchus.random.UnitSphereRandomVectorGenerator;
24 import org.hipparchus.util.FastMath;
25 import org.junit.After;
26 import org.junit.Assert;
27 import org.junit.Before;
28 import org.orekit.Utils;
29 import org.orekit.attitudes.AttitudeProvider;
30 import org.orekit.bodies.GeodeticPoint;
31 import org.orekit.bodies.OneAxisEllipsoid;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.errors.OrekitMessages;
34 import org.orekit.frames.FramesFactory;
35 import org.orekit.frames.TopocentricFrame;
36 import org.orekit.frames.Transform;
37 import org.orekit.orbits.KeplerianOrbit;
38 import org.orekit.orbits.Orbit;
39 import org.orekit.propagation.Propagator;
40 import org.orekit.propagation.SpacecraftState;
41 import org.orekit.propagation.analytical.KeplerianPropagator;
42 import org.orekit.propagation.events.VisibilityTrigger;
43 import org.orekit.time.AbsoluteDate;
44 import org.orekit.utils.Constants;
45 import org.orekit.utils.IERSConventions;
46 import org.orekit.utils.PVCoordinates;
47
48 public abstract class AbstractSmoothFieldOfViewTest {
49
50 protected void doTestFOVAwayFromEarth(final SmoothFieldOfView fov, final AttitudeProvider attitude,
51 final Vector3D expectedCenter) {
52 Assert.assertEquals(0.0, Vector3D.distance(expectedCenter, fov.getCenter()), 1.0e-15);
53 Propagator propagator = new KeplerianPropagator(orbit);
54 propagator.setAttitudeProvider(attitude);
55 SpacecraftState state = propagator.propagate(orbit.getDate().shiftedBy(1000.0));
56 Transform inertToBody = state.getFrame().getTransformTo(earth.getBodyFrame(), state.getDate());
57 Transform fovToBody = new Transform(state.getDate(),
58 state.toTransform().getInverse(),
59 inertToBody);
60 List<List<GeodeticPoint>> footprint = fov.getFootprint(fovToBody, earth, FastMath.toRadians(0.1));
61 Assert.assertTrue(footprint.isEmpty());
62 }
63
64 protected void doTestNoFootprintInside(final SmoothFieldOfView fov, final Transform fovToBody) {
65 try {
66 fov.getFootprint(fovToBody, earth, FastMath.toRadians(0.1));
67 Assert.fail("an exception should have been thrown");
68 } catch (OrekitException oe) {
69 Assert.assertEquals(OrekitMessages.POINT_INSIDE_ELLIPSOID, oe.getSpecifier());
70 }
71 }
72
73 protected void doTestFootprint(final SmoothFieldOfView fov, final AttitudeProvider attitude,
74 final double expectedMinOffset, final double expectedMaxOffset,
75 final double expectedMinElevation, final double expectedMaxElevation,
76 final double expectedMinDist, final double expectedMaxDist) {
77
78 Propagator propagator = new KeplerianPropagator(orbit);
79 propagator.setAttitudeProvider(attitude);
80 SpacecraftState state = propagator.propagate(orbit.getDate().shiftedBy(1000.0));
81 Transform inertToBody = state.getFrame().getTransformTo(earth.getBodyFrame(), state.getDate());
82 Transform fovToBody = new Transform(state.getDate(),
83 state.toTransform().getInverse(),
84 inertToBody);
85 List<List<GeodeticPoint>> footprint = fov.getFootprint(fovToBody, earth, FastMath.toRadians(0.1));
86 Vector3D subSat = earth.projectToGround(state.getPVCoordinates(earth.getBodyFrame()).getPosition(),
87 state.getDate(), earth.getBodyFrame());
88 Assert.assertEquals(1, footprint.size());
89 List<GeodeticPoint> loop = footprint.get(0);
90 double minOffset = Double.POSITIVE_INFINITY;
91 double maxOffset = 0;
92 double minEl = Double.POSITIVE_INFINITY;
93 double maxEl = 0;
94 double minDist = Double.POSITIVE_INFINITY;
95 double maxDist = 0;
96 for (int i = 0; i < loop.size(); ++i) {
97
98 Assert.assertEquals(0.0, loop.get(i).getAltitude(), 9.0e-9);
99
100 Vector3D los = fovToBody.getInverse().transformPosition(earth.transform(loop.get(i)));
101 double offset = Vector3D.angle(fov.getCenter(), los);
102 minOffset = FastMath.min(minOffset, offset);
103 maxOffset = FastMath.max(maxOffset, offset);
104
105 TopocentricFrame topo = new TopocentricFrame(earth, loop.get(i), "onFootprint");
106 final double elevation = topo.getElevation(state.getPVCoordinates().getPosition(),
107 state.getFrame(), state.getDate());
108 if (elevation > 0.001) {
109 Assert.assertEquals(-fov.getMargin(),
110 fov.offsetFromBoundary(los, 0.0, VisibilityTrigger.VISIBLE_ONLY_WHEN_FULLY_IN_FOV),
111 2.0e-10);
112 Assert.assertEquals(0.1 - fov.getMargin(),
113 fov.offsetFromBoundary(los, 0.1, VisibilityTrigger.VISIBLE_ONLY_WHEN_FULLY_IN_FOV),
114 2.0e-10);
115 Assert.assertEquals(-0.1 - fov.getMargin(),
116 fov.offsetFromBoundary(los, 0.1, VisibilityTrigger.VISIBLE_AS_SOON_AS_PARTIALLY_IN_FOV),
117 2.0e-10);
118 }
119 minEl = FastMath.min(minEl, elevation);
120 maxEl = FastMath.max(maxEl, elevation);
121 final double dist = Vector3D.distance(subSat, earth.transform(loop.get(i)));
122 minDist = FastMath.min(minDist, dist);
123 maxDist = FastMath.max(maxDist, dist);
124
125 }
126
127 Assert.assertEquals(expectedMinOffset, FastMath.toDegrees(minOffset), 0.001);
128 Assert.assertEquals(expectedMaxOffset, FastMath.toDegrees(maxOffset), 0.001);
129 Assert.assertEquals(expectedMinElevation, FastMath.toDegrees(minEl), 0.001);
130 Assert.assertEquals(expectedMaxElevation, FastMath.toDegrees(maxEl), 0.001);
131 Assert.assertEquals(expectedMinDist, minDist, 1.0);
132 Assert.assertEquals(expectedMaxDist, maxDist, 1.0);
133
134 }
135
136 protected void doTestBoundary(final SmoothFieldOfView fov, final RandomGenerator random,
137 final double tol) {
138 UnitSphereRandomVectorGenerator spGenerator = new UnitSphereRandomVectorGenerator(3, random);
139 for (int i = 0; i < 1000; ++i) {
140 Vector3D queryLOS = new Vector3D(spGenerator.nextVector());
141 Vector3D closest = fov.projectToBoundary(queryLOS);
142 Assert.assertEquals(-fov.getMargin(),
143 fov.offsetFromBoundary(closest, 0, VisibilityTrigger.VISIBLE_ONLY_WHEN_FULLY_IN_FOV),
144 tol);
145 }
146 }
147
148 @Before
149 public void setUp() {
150 Utils.setDataRoot("regular-data");
151 earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
152 Constants.WGS84_EARTH_FLATTENING,
153 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
154 orbit = new KeplerianOrbit(new PVCoordinates(new Vector3D(7.0e6, 1.0e6, 4.0e6),
155 new Vector3D(-500.0, 8000.0, 1000.0)),
156 FramesFactory.getEME2000(), AbsoluteDate.J2000_EPOCH,
157 Constants.EIGEN5C_EARTH_MU);
158 }
159
160 @After
161 public void tearDown() {
162 earth = null;
163 orbit = null;
164 }
165
166 protected OneAxisEllipsoid earth;
167 protected Orbit orbit;
168
169 }