Skip to content
Snippets Groups Projects
Commit ca2d810c authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Make use of OneAxisEllipsoid in EclipseDetector.

Work In Progress, the flattening is not used yet!
parent 6a3c0287
No related branches found
No related tags found
No related merge requests found
......@@ -16,12 +16,22 @@
*/
package org.orekit.propagation.events;
import org.hipparchus.RealFieldElement;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.ode.events.Action;
import org.hipparchus.util.FastMath;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.errors.OrekitInternalError;
import org.orekit.frames.FieldTransform;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.frames.Transform;
import org.orekit.frames.TransformProvider;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.handlers.EventHandler;
import org.orekit.propagation.events.handlers.StopOnIncreasing;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.utils.PVCoordinatesProvider;
/** Finder for satellite eclipse related events.
......@@ -37,10 +47,7 @@ import org.orekit.utils.PVCoordinatesProvider;
public class EclipseDetector extends AbstractDetector<EclipseDetector> {
/** Occulting body. */
private final PVCoordinatesProvider occulting;
/** Occulting body radius (m). */
private final double occultingRadius;
private final OneAxisEllipsoid occulting;
/** Occulted body. */
private final PVCoordinatesProvider occulted;
......@@ -51,6 +58,22 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
/** Umbra, if true, or penumbra, if false, detection flag. */
private final boolean totalEclipse;
/** Build a new eclipse detector.
* <p>The new instance is a total eclipse (umbra) detector with default
* values for maximal checking interval ({@link #DEFAULT_MAXCHECK})
* and convergence threshold ({@link #DEFAULT_THRESHOLD}).</p>
* @param occulted the body to be occulted
* @param occultedRadius the radius of the body to be occulted (m)
* @param occulting the occulting body
* @since 10.0
*/
public EclipseDetector(final PVCoordinatesProvider occulted, final double occultedRadius,
final OneAxisEllipsoid occulting) {
this(DEFAULT_MAXCHECK, DEFAULT_THRESHOLD, DEFAULT_MAX_ITER,
new StopOnIncreasing<EclipseDetector>(),
occulted, occultedRadius, occulting, true);
}
/** Build a new eclipse detector.
* <p>The new instance is a total eclipse (umbra) detector with default
* values for maximal checking interval ({@link #DEFAULT_MAXCHECK})
......@@ -101,7 +124,7 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
final PVCoordinatesProvider occulted, final double occultedRadius,
final PVCoordinatesProvider occulting, final double occultingRadius) {
this(maxCheck, threshold, DEFAULT_MAX_ITER, new StopOnIncreasing<EclipseDetector>(),
occulted, occultedRadius, occulting, occultingRadius, true);
occulted, occultedRadius, new SphericalOccultingBody(occulting, occultingRadius), true);
}
/** Private constructor with full parameters.
......@@ -117,21 +140,18 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
* @param occulted the body to be occulted
* @param occultedRadius the radius of the body to be occulted in meters
* @param occulting the occulting body
* @param occultingRadius the occulting body radius in meters
* @param totalEclipse umbra (true) or penumbra (false) detection flag
* @since 6.1
* @since 10.0
*/
private EclipseDetector(final double maxCheck, final double threshold,
final int maxIter, final EventHandler<? super EclipseDetector> handler,
final PVCoordinatesProvider occulted, final double occultedRadius,
final PVCoordinatesProvider occulting, final double occultingRadius,
final boolean totalEclipse) {
final OneAxisEllipsoid occulting, final boolean totalEclipse) {
super(maxCheck, threshold, maxIter, handler);
this.occulted = occulted;
this.occultedRadius = FastMath.abs(occultedRadius);
this.occulting = occulting;
this.occultingRadius = FastMath.abs(occultingRadius);
this.totalEclipse = totalEclipse;
this.occulted = occulted;
this.occultedRadius = FastMath.abs(occultedRadius);
this.occulting = occulting;
this.totalEclipse = totalEclipse;
}
/** {@inheritDoc} */
......@@ -139,7 +159,7 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
protected EclipseDetector create(final double newMaxCheck, final double newThreshold,
final int nawMaxIter, final EventHandler<? super EclipseDetector> newHandler) {
return new EclipseDetector(newMaxCheck, newThreshold, nawMaxIter, newHandler,
occulted, occultedRadius, occulting, occultingRadius, totalEclipse);
occulted, occultedRadius, occulting, totalEclipse);
}
/**
......@@ -153,8 +173,7 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
*/
public EclipseDetector withUmbra() {
return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(),
occulted, occultedRadius, occulting, occultingRadius,
true);
occulted, occultedRadius, occulting, true);
}
/**
......@@ -168,36 +187,7 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
*/
public EclipseDetector withPenumbra() {
return new EclipseDetector(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), getHandler(),
occulted, occultedRadius, occulting, occultingRadius,
false);
}
/** Get the occulting body.
* @return the occulting body
*/
public PVCoordinatesProvider getOcculting() {
return occulting;
}
/** Get the occulting body radius (m).
* @return the occulting body radius
*/
public double getOccultingRadius() {
return occultingRadius;
}
/** Get the occulted body.
* @return the occulted body
*/
public PVCoordinatesProvider getOcculted() {
return occulted;
}
/** Get the occulted body radius (m).
* @return the occulted body radius
*/
public double getOccultedRadius() {
return occultedRadius;
occulted, occultedRadius, occulting, false);
}
/** Get the total eclipse detection flag.
......@@ -215,21 +205,57 @@ public class EclipseDetector extends AbstractDetector<EclipseDetector> {
* @return value of the switching function
*/
public double g(final SpacecraftState s) {
final Vector3D pted = occulted.getPVCoordinates(s.getDate(), s.getFrame()).getPosition();
final Vector3D ping = occulting.getPVCoordinates(s.getDate(), s.getFrame()).getPosition();
final Vector3D psat = s.getPVCoordinates().getPosition();
final Vector3D ps = pted.subtract(psat);
final Vector3D po = ping.subtract(psat);
final double angle = Vector3D.angle(ps, po);
final Vector3D pted = occulted.getPVCoordinates(s.getDate(), occulting.getBodyFrame()).getPosition();
final Vector3D psat = s.getPVCoordinates(occulting.getBodyFrame()).getPosition();
final Vector3D ps = psat.subtract(pted);
final double angle = Vector3D.angle(ps, psat);
final double rs = FastMath.asin(occultedRadius / ps.getNorm());
if (Double.isNaN(rs)) {
return FastMath.PI;
}
final double ro = FastMath.asin(occultingRadius / po.getNorm());
final double ro = FastMath.asin(occulting.getEquatorialRadius() / psat.getNorm());
if (Double.isNaN(ro)) {
return -FastMath.PI;
}
return totalEclipse ? (angle - ro + rs) : (angle - ro - rs);
}
/** Temporary dummy ellipsoid for spherical occulting bodies.
* @deprecated as of 10.0, this class is a temporary intermediate for deprecated constructors
*/
@Deprecated
private static class SphericalOccultingBody extends OneAxisEllipsoid {
/** Serializable UID. */
private static final long serialVersionUID = 20190403L;
/** Simple constructor.
* @param occulting the occulting body
* @param occultingRadius the occulting body radius in meters
*/
SphericalOccultingBody(final PVCoordinatesProvider occulting, final double occultingRadius) {
super(occultingRadius, 0.0,
new Frame(FramesFactory.getEME2000(),
new TransformProvider() {
/** Serializable UID. */
private static final long serialVersionUID = 20190403L;
/** {@inheritDoc} */
@Override
public Transform getTransform(final AbsoluteDate date) {
return new Transform(date, occulting.getPVCoordinates(date, FramesFactory.getEME2000()));
}
/** {@inheritDoc} */
@Override
public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
// never called
throw new OrekitInternalError(null);
}
}, "dummy"));
}
}
}
......@@ -16,6 +16,8 @@
*/
package org.orekit.propagation.events;
import java.util.List;
import org.hipparchus.exception.MathRuntimeException;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
......@@ -28,16 +30,24 @@ import org.junit.Test;
import org.orekit.Utils;
import org.orekit.bodies.CelestialBody;
import org.orekit.bodies.CelestialBodyFactory;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.errors.OrekitException;
import org.orekit.frames.FramesFactory;
import org.orekit.orbits.CartesianOrbit;
import org.orekit.orbits.EquinoctialOrbit;
import org.orekit.orbits.KeplerianOrbit;
import org.orekit.orbits.Orbit;
import org.orekit.orbits.OrbitType;
import org.orekit.orbits.PositionAngle;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.EventsLogger.LoggedEvent;
import org.orekit.propagation.events.handlers.ContinueOnEvent;
import org.orekit.propagation.events.handlers.StopOnDecreasing;
import org.orekit.propagation.numerical.NumericalPropagator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.TimeStampedPVCoordinates;
......@@ -53,6 +63,51 @@ public class EclipseDetectorTest {
private double sunRadius;
private double earthRadius;
@Test
public void testPolar() {
final KeplerianOrbit original = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(initialState.getOrbit());
final KeplerianOrbit polar = new KeplerianOrbit(original.getA(), original.getE(),
0.5 * FastMath.PI, original.getPerigeeArgument(),
original.getRightAscensionOfAscendingNode(),
original.getTrueAnomaly(), PositionAngle.TRUE,
original.getFrame(), original.getDate(),
original.getMu());
propagator.resetInitialState(new SpacecraftState(polar));
EventsLogger logger = new EventsLogger();
EclipseDetector withoutFlattening = new EclipseDetector(60., 1.e-3,
sun, sunRadius,
earth, earthRadius).
withHandler(new ContinueOnEvent<>()).
withUmbra();
// EclipseDetector withFlattening = new EclipseDetector(sun, sunRadius,
// new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
// Constants.WGS84_EARTH_FLATTENING,
// FramesFactory.getITRF(IERSConventions.IERS_2010,
// true))).
// withMaxCheck(60.0).
// withThreshold(1.0e-3).
// withHandler(new ContinueOnEvent<>()).
// withUmbra();
propagator.addEventDetector(logger.monitorDetector(withoutFlattening));
// propagator.addEventDetector(logger.monitorDetector(withFlattening));
double duration = 15000.0;
final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(duration));
Assert.assertEquals(duration, finalState.getDate().durationFrom(iniDate), 1.0e-3);
final List<LoggedEvent> events = logger.getLoggedEvents();
Assert.assertEquals(5, events.size());
Assert.assertTrue(events.get(0).getEventDetector() == withoutFlattening);
Assert.assertEquals( 2267.267, events.get(0).getState().getDate().durationFrom(iniDate), 1.0e-3);
Assert.assertTrue(events.get(1).getEventDetector() == withoutFlattening);
Assert.assertEquals( 4324.592, events.get(1).getState().getDate().durationFrom(iniDate), 1.0e-3);
Assert.assertTrue(events.get(2).getEventDetector() == withoutFlattening);
Assert.assertEquals( 8181.819, events.get(2).getState().getDate().durationFrom(iniDate), 1.0e-3);
Assert.assertTrue(events.get(3).getEventDetector() == withoutFlattening);
Assert.assertEquals(10239.549, events.get(3).getState().getDate().durationFrom(iniDate), 1.0e-3);
Assert.assertTrue(events.get(4).getEventDetector() == withoutFlattening);
Assert.assertEquals(14096.372, events.get(4).getState().getDate().durationFrom(iniDate), 1.0e-3);
}
@Test
public void testEclipse() {
EclipseDetector e = new EclipseDetector(60., 1.e-3,
......@@ -63,10 +118,6 @@ public class EclipseDetectorTest {
Assert.assertEquals(60.0, e.getMaxCheckInterval(), 1.0e-15);
Assert.assertEquals(1.0e-3, e.getThreshold(), 1.0e-15);
Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, e.getMaxIterationCount());
Assert.assertSame(sun, e.getOcculted());
Assert.assertEquals(sunRadius, e.getOccultedRadius(), 1.0);
Assert.assertSame(earth, e.getOcculting());
Assert.assertEquals(earthRadius, e.getOccultingRadius(), 1.0);
Assert.assertTrue(e.getTotalEclipse());
propagator.addEventDetector(e);
final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(6000));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment