use of org.orekit.propagation.events.EclipseDetector in project Orekit by CS-SI.
the class AttitudesSequenceTest method doTestDayNightSwitchField.
private <T extends RealFieldElement<T>> void doTestDayNightSwitchField(final Field<T> field) throws OrekitException {
// Initial state definition : date, orbit
final FieldAbsoluteDate<T> initialDate = new FieldAbsoluteDate<>(field, 2004, 01, 01, 23, 30, 00.000, TimeScalesFactory.getUTC());
final FieldVector3D<T> position = new FieldVector3D<>(field, new Vector3D(-6142438.668, 3492467.560, -25767.25680));
final FieldVector3D<T> velocity = new FieldVector3D<>(field, new Vector3D(505.8479685, 942.7809215, 7435.922231));
final FieldOrbit<T> initialOrbit = new FieldKeplerianOrbit<>(new FieldPVCoordinates<>(position, velocity), FramesFactory.getEME2000(), initialDate, Constants.EIGEN5C_EARTH_MU);
// Attitudes sequence definition
EventsLogger logger = new EventsLogger();
final AttitudesSequence attitudesSequence = new AttitudesSequence();
final AttitudeProvider dayObservationLaw = new LofOffset(initialOrbit.getFrame(), LOFType.VVLH, RotationOrder.XYZ, FastMath.toRadians(20), FastMath.toRadians(40), 0);
final AttitudeProvider nightRestingLaw = new LofOffset(initialOrbit.getFrame(), LOFType.VVLH);
final PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
final PVCoordinatesProvider earth = CelestialBodyFactory.getEarth();
final EclipseDetector ed = new EclipseDetector(sun, 696000000., earth, Constants.WGS84_EARTH_EQUATORIAL_RADIUS).withHandler(new ContinueOnEvent<EclipseDetector>() {
private static final long serialVersionUID = 1L;
int count = 0;
public EventHandler.Action eventOccurred(final SpacecraftState s, final EclipseDetector d, final boolean increasing) {
setInEclipse(s.getDate(), !increasing);
if (count++ == 7) {
return Action.STOP;
} else {
switch(count % 3) {
case 0:
return Action.CONTINUE;
case 1:
return Action.RESET_DERIVATIVES;
default:
return Action.RESET_STATE;
}
}
}
});
final EventDetector monitored = logger.monitorDetector(ed);
final Handler dayToNightHandler = new Handler(dayObservationLaw, nightRestingLaw);
final Handler nightToDayHandler = new Handler(nightRestingLaw, dayObservationLaw);
attitudesSequence.addSwitchingCondition(dayObservationLaw, nightRestingLaw, monitored, false, true, 300.0, AngularDerivativesFilter.USE_RRA, dayToNightHandler);
attitudesSequence.addSwitchingCondition(nightRestingLaw, dayObservationLaw, monitored, true, false, 300.0, AngularDerivativesFilter.USE_RRA, nightToDayHandler);
FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(initialOrbit);
initialState = initialState.addAdditionalState("fortyTwo", field.getZero().add(42.0));
if (ed.g(initialState.toSpacecraftState()) >= 0) {
// initial position is in daytime
setInEclipse(initialDate.toAbsoluteDate(), false);
attitudesSequence.resetActiveProvider(dayObservationLaw);
} else {
// initial position is in nighttime
setInEclipse(initialDate.toAbsoluteDate(), true);
attitudesSequence.resetActiveProvider(nightRestingLaw);
}
// Propagator : consider the analytical Eckstein-Hechler model
final FieldPropagator<T> propagator = new FieldEcksteinHechlerPropagator<T>(initialOrbit, attitudesSequence, Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU, Constants.EIGEN5C_EARTH_C20, Constants.EIGEN5C_EARTH_C30, Constants.EIGEN5C_EARTH_C40, Constants.EIGEN5C_EARTH_C50, Constants.EIGEN5C_EARTH_C60);
// Register the switching events to the propagator
attitudesSequence.registerSwitchEvents(field, propagator);
propagator.setMasterMode(field.getZero().add(60.0), new FieldOrekitFixedStepHandler<T>() {
public void handleStep(FieldSpacecraftState<T> currentState, boolean isLast) throws OrekitException {
// the Earth position in spacecraft frame should be along spacecraft Z axis
// during night time and away from it during day time due to roll and pitch offsets
final FieldVector3D<T> earth = currentState.toTransform().transformPosition(Vector3D.ZERO);
final T pointingOffset = FieldVector3D.angle(earth, Vector3D.PLUS_K);
// the g function is the eclipse indicator, its an angle between Sun and Earth limb,
// positive when Sun is outside of Earth limb, negative when Sun is hidden by Earth limb
final double eclipseAngle = ed.g(currentState.toSpacecraftState());
if (currentState.getDate().durationFrom(lastChange).getReal() > 300) {
if (inEclipse) {
Assert.assertTrue(eclipseAngle <= 0);
Assert.assertEquals(0.0, pointingOffset.getReal(), 1.0e-6);
} else {
Assert.assertTrue(eclipseAngle >= 0);
Assert.assertEquals(0.767215, pointingOffset.getReal(), 1.0e-6);
}
} else {
// we are in transition
Assert.assertTrue(pointingOffset.getReal() + " " + (0.767215 - pointingOffset.getReal()), pointingOffset.getReal() <= 0.7672155);
}
}
});
// Propagate from the initial date for the fixed duration
propagator.propagate(initialDate.shiftedBy(12600.));
// as we have 2 switch events (even if they share the same underlying event detector),
// and these events are triggered at both eclipse entry and exit, we get 8
// raw events on 2 orbits
Assert.assertEquals(8, logger.getLoggedEvents().size());
// we have 4 attitudes switch on 2 orbits, 2 of each type
Assert.assertEquals(2, dayToNightHandler.dates.size());
Assert.assertEquals(2, nightToDayHandler.dates.size());
}
use of org.orekit.propagation.events.EclipseDetector in project Orekit by CS-SI.
the class AttitudesSequenceTest method testDayNightSwitch.
@Test
public void testDayNightSwitch() throws OrekitException {
// Initial state definition : date, orbit
final AbsoluteDate initialDate = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000, TimeScalesFactory.getUTC());
final Vector3D position = new Vector3D(-6142438.668, 3492467.560, -25767.25680);
final Vector3D velocity = new Vector3D(505.8479685, 942.7809215, 7435.922231);
final Orbit initialOrbit = new KeplerianOrbit(new PVCoordinates(position, velocity), FramesFactory.getEME2000(), initialDate, Constants.EIGEN5C_EARTH_MU);
final EventsLogger // Attitudes sequence definition
logger = new EventsLogger();
final AttitudesSequence attitudesSequence = new AttitudesSequence();
final AttitudeProvider dayObservationLaw = new LofOffset(initialOrbit.getFrame(), LOFType.VVLH, RotationOrder.XYZ, FastMath.toRadians(20), FastMath.toRadians(40), 0);
final AttitudeProvider nightRestingLaw = new LofOffset(initialOrbit.getFrame(), LOFType.VVLH);
final PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
final PVCoordinatesProvider earth = CelestialBodyFactory.getEarth();
final EclipseDetector ed = new EclipseDetector(sun, 696000000., earth, Constants.WGS84_EARTH_EQUATORIAL_RADIUS).withHandler(new ContinueOnEvent<EclipseDetector>() {
private static final long serialVersionUID = 1L;
public EventHandler.Action eventOccurred(final SpacecraftState s, final EclipseDetector d, final boolean increasing) {
setInEclipse(s.getDate(), !increasing);
return EventHandler.Action.RESET_STATE;
}
});
final EventDetector monitored = logger.monitorDetector(ed);
final Handler dayToNightHandler = new Handler(dayObservationLaw, nightRestingLaw);
final Handler nightToDayHandler = new Handler(nightRestingLaw, dayObservationLaw);
attitudesSequence.addSwitchingCondition(dayObservationLaw, nightRestingLaw, monitored, false, true, 300.0, AngularDerivativesFilter.USE_RRA, dayToNightHandler);
attitudesSequence.addSwitchingCondition(nightRestingLaw, dayObservationLaw, monitored, true, false, 300.0, AngularDerivativesFilter.USE_RRA, nightToDayHandler);
SpacecraftState initialState = new SpacecraftState(initialOrbit);
initialState = initialState.addAdditionalState("fortyTwo", 42.0);
if (ed.g(initialState) >= 0) {
// initial position is in daytime
setInEclipse(initialDate, false);
attitudesSequence.resetActiveProvider(dayObservationLaw);
} else {
// initial position is in nighttime
setInEclipse(initialDate, true);
attitudesSequence.resetActiveProvider(nightRestingLaw);
}
// Propagator : consider the analytical Eckstein-Hechler model
final Propagator propagator = new EcksteinHechlerPropagator(initialOrbit, attitudesSequence, Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU, Constants.EIGEN5C_EARTH_C20, Constants.EIGEN5C_EARTH_C30, Constants.EIGEN5C_EARTH_C40, Constants.EIGEN5C_EARTH_C50, Constants.EIGEN5C_EARTH_C60);
// Register the switching events to the propagator
attitudesSequence.registerSwitchEvents(propagator);
propagator.setMasterMode(60.0, new OrekitFixedStepHandler() {
public void handleStep(SpacecraftState currentState, boolean isLast) throws OrekitException {
// the Earth position in spacecraft frame should be along spacecraft Z axis
// during night time and away from it during day time due to roll and pitch offsets
final Vector3D earth = currentState.toTransform().transformPosition(Vector3D.ZERO);
final double pointingOffset = Vector3D.angle(earth, Vector3D.PLUS_K);
// the g function is the eclipse indicator, its an angle between Sun and Earth limb,
// positive when Sun is outside of Earth limb, negative when Sun is hidden by Earth limb
final double eclipseAngle = ed.g(currentState);
if (currentState.getDate().durationFrom(lastChange) > 300) {
if (inEclipse) {
Assert.assertTrue(eclipseAngle <= 0);
Assert.assertEquals(0.0, pointingOffset, 1.0e-6);
} else {
Assert.assertTrue(eclipseAngle >= 0);
Assert.assertEquals(0.767215, pointingOffset, 1.0e-6);
}
} else {
// we are in transition
Assert.assertTrue(pointingOffset + " " + (0.767215 - pointingOffset), pointingOffset <= 0.7672155);
}
}
});
// Propagate from the initial date for the fixed duration
propagator.propagate(initialDate.shiftedBy(12600.));
// as we have 2 switch events (even if they share the same underlying event detector),
// and these events are triggered at both eclipse entry and exit, we get 8
// raw events on 2 orbits
Assert.assertEquals(8, logger.getLoggedEvents().size());
// we have 4 attitudes switch on 2 orbits, 2 of each type
Assert.assertEquals(2, dayToNightHandler.dates.size());
Assert.assertEquals(2, nightToDayHandler.dates.size());
}
use of org.orekit.propagation.events.EclipseDetector in project Orekit by CS-SI.
the class EphemerisEventsTest method buildEclipsDetector.
private EclipseDetector buildEclipsDetector(final OrbitType type) throws OrekitException {
double sunRadius = 696000000.;
double earthRadius = 6400000.;
EclipseDetector ecl = new EclipseDetector(60., 1.e-3, CelestialBodyFactory.getSun(), sunRadius, CelestialBodyFactory.getEarth(), earthRadius).withHandler(new EventHandler<EclipseDetector>() {
public Action eventOccurred(SpacecraftState s, EclipseDetector detector, boolean increasing) throws OrekitException {
Assert.assertEquals(type, s.getOrbit().getType());
if (increasing) {
++inEclipsecounter;
} else {
++outEclipsecounter;
}
return Action.CONTINUE;
}
});
return ecl;
}
use of org.orekit.propagation.events.EclipseDetector in project Orekit by CS-SI.
the class EarthObservation method main.
/**
* Program entry point.
* @param args program arguments (unused here)
*/
public static void main(String[] args) {
try {
// configure Orekit
File home = new File(System.getProperty("user.home"));
File orekitData = new File(home, "orekit-data");
if (!orekitData.exists()) {
System.err.format(Locale.US, "Failed to find %s folder%n", orekitData.getAbsolutePath());
System.err.format(Locale.US, "You need to download %s from the %s page and unzip it in %s for this tutorial to work%n", "orekit-data.zip", "https://www.orekit.org/forge/projects/orekit/files", home.getAbsolutePath());
System.exit(1);
}
DataProvidersManager manager = DataProvidersManager.getInstance();
manager.addProvider(new DirectoryCrawler(orekitData));
final SortedSet<String> output = new TreeSet<String>();
// Initial state definition : date, orbit
final AbsoluteDate initialDate = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000, TimeScalesFactory.getUTC());
final Vector3D position = new Vector3D(-6142438.668, 3492467.560, -25767.25680);
final Vector3D velocity = new Vector3D(505.8479685, 942.7809215, 7435.922231);
final Orbit initialOrbit = new KeplerianOrbit(new PVCoordinates(position, velocity), FramesFactory.getEME2000(), initialDate, Constants.EIGEN5C_EARTH_MU);
// Attitudes sequence definition
final AttitudeProvider dayObservationLaw = new LofOffset(initialOrbit.getFrame(), LOFType.VVLH, RotationOrder.XYZ, FastMath.toRadians(20), FastMath.toRadians(40), 0);
final AttitudeProvider nightRestingLaw = new LofOffset(initialOrbit.getFrame(), LOFType.VVLH);
final PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
final PVCoordinatesProvider earth = CelestialBodyFactory.getEarth();
final EventDetector dayNightEvent = new EclipseDetector(sun, 696000000., earth, Constants.WGS84_EARTH_EQUATORIAL_RADIUS).withHandler(new ContinueOnEvent<EclipseDetector>());
final EventDetector nightDayEvent = new EclipseDetector(sun, 696000000., earth, Constants.WGS84_EARTH_EQUATORIAL_RADIUS).withHandler(new ContinueOnEvent<EclipseDetector>());
final AttitudesSequence attitudesSequence = new AttitudesSequence();
final AttitudesSequence.SwitchHandler switchHandler = new AttitudesSequence.SwitchHandler() {
public void switchOccurred(AttitudeProvider preceding, AttitudeProvider following, SpacecraftState s) {
if (preceding == dayObservationLaw) {
output.add(s.getDate() + ": switching to night law");
} else {
output.add(s.getDate() + ": switching to day law");
}
}
};
attitudesSequence.addSwitchingCondition(dayObservationLaw, nightRestingLaw, dayNightEvent, false, true, 10.0, AngularDerivativesFilter.USE_R, switchHandler);
attitudesSequence.addSwitchingCondition(nightRestingLaw, dayObservationLaw, nightDayEvent, true, false, 10.0, AngularDerivativesFilter.USE_R, switchHandler);
if (dayNightEvent.g(new SpacecraftState(initialOrbit)) >= 0) {
// initial position is in daytime
attitudesSequence.resetActiveProvider(dayObservationLaw);
} else {
// initial position is in nighttime
attitudesSequence.resetActiveProvider(nightRestingLaw);
}
// Propagator : consider the analytical Eckstein-Hechler model
final Propagator propagator = new EcksteinHechlerPropagator(initialOrbit, attitudesSequence, Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU, Constants.EIGEN5C_EARTH_C20, Constants.EIGEN5C_EARTH_C30, Constants.EIGEN5C_EARTH_C40, Constants.EIGEN5C_EARTH_C50, Constants.EIGEN5C_EARTH_C60);
// Register the switching events to the propagator
attitudesSequence.registerSwitchEvents(propagator);
propagator.setMasterMode(180.0, new OrekitFixedStepHandler() {
public void init(final SpacecraftState s0, final AbsoluteDate t) {
}
public void handleStep(SpacecraftState currentState, boolean isLast) throws OrekitException {
DecimalFormatSymbols angleDegree = new DecimalFormatSymbols(Locale.US);
angleDegree.setDecimalSeparator('\u00b0');
DecimalFormat ad = new DecimalFormat(" 00.000;-00.000", angleDegree);
// the Earth position in spacecraft frame should be along spacecraft Z axis
// during nigthtime and away from it during daytime due to roll and pitch offsets
final Vector3D earth = currentState.toTransform().transformPosition(Vector3D.ZERO);
final double pointingOffset = Vector3D.angle(earth, Vector3D.PLUS_K);
// the g function is the eclipse indicator, its an angle between Sun and Earth limb,
// positive when Sun is outside of Earth limb, negative when Sun is hidden by Earth limb
final double eclipseAngle = dayNightEvent.g(currentState);
output.add(currentState.getDate() + " " + ad.format(FastMath.toDegrees(eclipseAngle)) + " " + ad.format(FastMath.toDegrees(pointingOffset)));
}
});
// Propagate from the initial date for the fixed duration
SpacecraftState finalState = propagator.propagate(initialDate.shiftedBy(12600.));
// to make sure out of orders calls between step handler and event handlers don't mess things up
for (final String line : output) {
System.out.println(line);
}
System.out.println("Propagation ended at " + finalState.getDate());
} catch (OrekitException oe) {
System.err.println(oe.getMessage());
}
}
Aggregations