From 9e384b2ca7e7c264bd8e8a1ff88866e707ccf4f7 Mon Sep 17 00:00:00 2001 From: "dmitry.walther" Date: Tue, 6 Oct 2020 13:03:17 +0300 Subject: [PATCH 1/2] Finder for sub-satellite point eclipse related events --- .../propagation/events/EclipseDetector.java | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/orekit/propagation/events/EclipseDetector.java b/src/main/java/org/orekit/propagation/events/EclipseDetector.java index 1ca60747f4..3df6448184 100644 --- a/src/main/java/org/orekit/propagation/events/EclipseDetector.java +++ b/src/main/java/org/orekit/propagation/events/EclipseDetector.java @@ -19,7 +19,10 @@ import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.ode.events.Action; import org.hipparchus.util.FastMath; +import org.orekit.bodies.GeodeticPoint; import org.orekit.bodies.OneAxisEllipsoid; +import org.orekit.frames.Frame; +import org.orekit.frames.FramesFactory; import org.orekit.propagation.SpacecraftState; import org.orekit.propagation.events.handlers.EventHandler; import org.orekit.propagation.events.handlers.StopOnIncreasing; @@ -61,6 +64,9 @@ public class EclipseDetector extends AbstractDetector { /** Umbra, if true, or penumbra, if false, detection flag. */ private final boolean totalEclipse; + + /** Sub-satellite point, if true, or Spacecraft, if false, detection flag. */ + private final boolean subSatellitePoint; /** Build a new eclipse detector. *

The new instance is a total eclipse (umbra) detector with default @@ -75,7 +81,7 @@ public EclipseDetector(final PVCoordinatesProvider occulted, final double occul final OneAxisEllipsoid occulting) { this(DEFAULT_MAXCHECK, DEFAULT_THRESHOLD, DEFAULT_MAX_ITER, new StopOnIncreasing(), - occulted, occultedRadius, occulting, true); + occulted, occultedRadius, occulting, true, false); } /** Private constructor with full parameters. @@ -92,17 +98,20 @@ public EclipseDetector(final PVCoordinatesProvider occulted, final double occul * @param occultedRadius the radius of the body to be occulted in meters * @param occulting the occulting body * @param totalEclipse umbra (true) or penumbra (false) detection flag + * @param subSatellitePoint Sub-satellite point (true) or Spacecraft (false) flag * @since 10.0 */ private EclipseDetector(final double maxCheck, final double threshold, final int maxIter, final EventHandler handler, final PVCoordinatesProvider occulted, final double occultedRadius, - final OneAxisEllipsoid occulting, final boolean totalEclipse) { + final OneAxisEllipsoid occulting, final boolean totalEclipse, final boolean subSatellitePoint) { super(maxCheck, threshold, maxIter, handler); this.occulted = occulted; this.occultedRadius = FastMath.abs(occultedRadius); this.occulting = occulting; this.totalEclipse = totalEclipse; + this.subSatellitePoint = subSatellitePoint; + } /** {@inheritDoc} */ @@ -110,11 +119,11 @@ private EclipseDetector(final double maxCheck, final double threshold, protected EclipseDetector create(final double newMaxCheck, final double newThreshold, final int nawMaxIter, final EventHandler newHandler) { return new EclipseDetector(newMaxCheck, newThreshold, nawMaxIter, newHandler, - occulted, occultedRadius, occulting, totalEclipse); + occulted, occultedRadius, occulting, totalEclipse, subSatellitePoint); } /** - * Setup the detector to full umbra detection. + * Setup the detector to full umbra detection for the satellite. *

* This will override a penumbra/umbra flag if it has been configured previously. *

@@ -124,21 +133,47 @@ protected EclipseDetector create(final double newMaxCheck, final double newThres */ public EclipseDetector withUmbra() { return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), - occulted, occultedRadius, occulting, true); + occulted, occultedRadius, occulting, true, false); } - + /** - * Setup the detector to penumbra detection. + * Setup the detector to full umbra detection for the sub-satellite point. *

* This will override a penumbra/umbra flag if it has been configured previously. *

* @return a new detector with updated configuration (the instance is not changed) - * @see #withUmbra() + * @see #withPenumbra() * @since 6.1 */ + public EclipseDetector UmbraWithSSP() { + return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), + occulted, occultedRadius, occulting, true, true); + } + + /** + * Setup the detector to penumbra detection for the satellite. + *

+ * This will override a penumbra/umbra flag if it has been configured previously. + *

+ * @return a new detector with updated configuration (the instance is not changed) + * @see #penumbraWithSSP() + */ public EclipseDetector withPenumbra() { return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), - occulted, occultedRadius, occulting, false); + occulted, occultedRadius, occulting, false, false); + } + + /** + * Setup the detector to penumbra detection for the sub-satellite point. + *

+ * This will override a penumbra/umbra flag if it has been configured previously. + *

+ * @return a new detector with updated configuration (the instance is not changed) + * @see #UmbraWithSSP() + */ + public EclipseDetector penumbraWithSSP() { + return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), + occulted, occultedRadius, occulting, false, true); } /** Getter for the occulting body. @@ -169,6 +204,14 @@ public double getOccultedRadius() { public boolean getTotalEclipse() { return totalEclipse; } + + /** Get the sub-satellite point flag. + * @return the sub-satellite point flag (true for sub-satellite point, + * false for satellite) + */ + public boolean getSubSatellitePoint() { + return subSatellitePoint; + } /** Compute the value of the switching function. * This function becomes negative when entering the region of shadow @@ -178,7 +221,15 @@ public boolean getTotalEclipse() { */ public double g(final SpacecraftState s) { final Vector3D pted = occulted.getPVCoordinates(s.getDate(), occulting.getBodyFrame()).getPosition(); - final Vector3D psat = s.getPVCoordinates(occulting.getBodyFrame()).getPosition(); + Vector3D psat = null; + if (subSatellitePoint) { + Frame inertialFrame = FramesFactory.getEME2000(); + GeodeticPoint gp = getOcculting().transform(s.getPVCoordinates().getPosition(), inertialFrame, s.getDate()); + GeodeticPoint gpSSP = new GeodeticPoint(gp.getLatitude(), gp.getLongitude(), 1); + psat = getOcculting().transform(gpSSP); + } else { + psat = s.getPVCoordinates(occulting.getBodyFrame()).getPosition(); + } final Vector3D plimb = occulting.pointOnLimb(psat, pted); final Vector3D ps = psat.subtract(pted); final Vector3D pi = psat.subtract(plimb); From 8a6508dc50693d8defe1d42e6b2cfa6fc5f40e17 Mon Sep 17 00:00:00 2001 From: "dmitry.walther" Date: Wed, 7 Oct 2020 16:12:46 +0300 Subject: [PATCH 2/2] The inertial frame is extracted from SpacecraftState. One method withSubSatellitePoint() was added instead withUmbraSSP and withPenumbraSSP methods. Unit test was added for the method withSubSatellitePoint(). --- .../propagation/events/EclipseDetector.java | 33 +++++-------------- .../events/EclipseDetectorTest.java | 12 +++++++ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/orekit/propagation/events/EclipseDetector.java b/src/main/java/org/orekit/propagation/events/EclipseDetector.java index 3df6448184..367e0a7162 100644 --- a/src/main/java/org/orekit/propagation/events/EclipseDetector.java +++ b/src/main/java/org/orekit/propagation/events/EclipseDetector.java @@ -65,8 +65,8 @@ public class EclipseDetector extends AbstractDetector { /** Umbra, if true, or penumbra, if false, detection flag. */ private final boolean totalEclipse; - /** Sub-satellite point, if true, or Spacecraft, if false, detection flag. */ - private final boolean subSatellitePoint; + /** Sub-satellite point, if true, or Spacecraft, if false (default), flag. */ + private boolean subSatellitePoint = false; /** Build a new eclipse detector. *

The new instance is a total eclipse (umbra) detector with default @@ -133,23 +133,9 @@ protected EclipseDetector create(final double newMaxCheck, final double newThres */ public EclipseDetector withUmbra() { return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), - occulted, occultedRadius, occulting, true, false); + occulted, occultedRadius, occulting, true, subSatellitePoint); } - /** - * Setup the detector to full umbra detection for the sub-satellite point. - *

- * This will override a penumbra/umbra flag if it has been configured previously. - *

- * @return a new detector with updated configuration (the instance is not changed) - * @see #withPenumbra() - * @since 6.1 - */ - public EclipseDetector UmbraWithSSP() { - return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), - occulted, occultedRadius, occulting, true, true); - } - /** * Setup the detector to penumbra detection for the satellite. *

@@ -160,20 +146,17 @@ public EclipseDetector UmbraWithSSP() { */ public EclipseDetector withPenumbra() { return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), - occulted, occultedRadius, occulting, false, false); + occulted, occultedRadius, occulting, false, subSatellitePoint); } /** - * Setup the detector to penumbra detection for the sub-satellite point. + * Setup the detector for the sub-satellite point. *

- * This will override a penumbra/umbra flag if it has been configured previously. - *

* @return a new detector with updated configuration (the instance is not changed) - * @see #UmbraWithSSP() */ - public EclipseDetector penumbraWithSSP() { + public EclipseDetector withSubSatellitePoint() { return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(), - occulted, occultedRadius, occulting, false, true); + occulted, occultedRadius, occulting, totalEclipse, true); } /** Getter for the occulting body. @@ -223,7 +206,7 @@ public double g(final SpacecraftState s) { final Vector3D pted = occulted.getPVCoordinates(s.getDate(), occulting.getBodyFrame()).getPosition(); Vector3D psat = null; if (subSatellitePoint) { - Frame inertialFrame = FramesFactory.getEME2000(); + Frame inertialFrame = s.getFrame(); GeodeticPoint gp = getOcculting().transform(s.getPVCoordinates().getPosition(), inertialFrame, s.getDate()); GeodeticPoint gpSSP = new GeodeticPoint(gp.getLatitude(), gp.getLongitude(), 1); psat = getOcculting().transform(gpSSP); diff --git a/src/test/java/org/orekit/propagation/events/EclipseDetectorTest.java b/src/test/java/org/orekit/propagation/events/EclipseDetectorTest.java index cae8a97815..0af9cbf5cf 100644 --- a/src/test/java/org/orekit/propagation/events/EclipseDetectorTest.java +++ b/src/test/java/org/orekit/propagation/events/EclipseDetectorTest.java @@ -159,6 +159,18 @@ public void testPenumbra() { final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(4388.155852, finalState.getDate().durationFrom(iniDate), 2.0e-6); } + + @Test + public void testSubSatellitePoint() { + EclipseDetector e = new EclipseDetector(sun, sunRadius, earth). + withMaxCheck(60.0). + withThreshold(1.0e-3). + withUmbra().withSubSatellitePoint(); + Assert.assertTrue(e.getTotalEclipse()); + propagator.addEventDetector(e); + final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(6000)); + Assert.assertEquals(4815.310605, finalState.getDate().durationFrom(iniDate), 2.0e-6); + } @Test public void testWithMethods() {