use of org.orekit.propagation.events.EventsLogger in project Orekit by CS-SI.
the class OrekitEphemerisFileTest method testWritingToOEM.
@Test
public void testWritingToOEM() throws OrekitException, IOException {
final double muTolerance = 1e-12;
final double positionTolerance = 1e-8;
final double velocityTolerance = 1e-8;
final String satId = "SATELLITE1";
final double sma = 10000000;
final double inc = Math.toRadians(45.0);
final double ecc = 0.001;
final double raan = 0.0;
final double pa = 0.0;
final double ta = 0.0;
final AbsoluteDate date = new AbsoluteDate();
final Frame frame = FramesFactory.getGCRF();
final CelestialBody body = CelestialBodyFactory.getEarth();
final double mu = body.getGM();
KeplerianOrbit initialOrbit = new KeplerianOrbit(sma, ecc, inc, pa, raan, ta, PositionAngle.TRUE, frame, date, mu);
KeplerianPropagator propagator = new KeplerianPropagator(initialOrbit);
final double propagationDurationSeconds = 86400.0;
final double stepSizeSeconds = 60.0;
List<SpacecraftState> states = new ArrayList<SpacecraftState>();
for (double dt = 0.0; dt < propagationDurationSeconds; dt += stepSizeSeconds) {
states.add(propagator.propagate(date.shiftedBy(dt)));
}
OrekitEphemerisFile ephemerisFile = new OrekitEphemerisFile();
OrekitSatelliteEphemeris satellite = ephemerisFile.addSatellite(satId);
satellite.addNewSegment(states);
String tempOemFile = Files.createTempFile("OrekitEphemerisFileTest", ".oem").toString();
new OEMWriter().write(tempOemFile, ephemerisFile);
EphemerisFile ephemerisFromFile = new OEMParser().parse(tempOemFile);
Files.delete(Paths.get(tempOemFile));
EphemerisSegment segment = ephemerisFromFile.getSatellites().get(satId).getSegments().get(0);
assertEquals(states.get(0).getDate(), segment.getStart());
assertEquals(states.get(states.size() - 1).getDate(), segment.getStop());
assertEquals(states.size(), segment.getCoordinates().size());
assertEquals(frame, segment.getFrame());
assertEquals(body.getName().toUpperCase(), segment.getFrameCenterString());
assertEquals(body.getGM(), segment.getMu(), muTolerance);
for (int i = 0; i < states.size(); i++) {
TimeStampedPVCoordinates expected = states.get(i).getPVCoordinates();
TimeStampedPVCoordinates actual = segment.getCoordinates().get(i);
assertEquals(expected.getDate(), actual.getDate());
assertEquals(0.0, Vector3D.distance(expected.getPosition(), actual.getPosition()), positionTolerance);
assertEquals(0.0, Vector3D.distance(expected.getVelocity(), actual.getVelocity()), velocityTolerance);
}
// test ingested ephemeris generates access intervals
final OneAxisEllipsoid parentShape = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true));
final double latitude = 0.0;
final double longitude = 0.0;
final double altitude = 0.0;
final GeodeticPoint point = new GeodeticPoint(latitude, longitude, altitude);
final TopocentricFrame topo = new TopocentricFrame(parentShape, point, "testPoint1");
final ElevationDetector elevationDetector = new ElevationDetector(topo);
final EphemerisSegmentPropagator ephemerisSegmentPropagator = new EphemerisSegmentPropagator(segment);
final EventsLogger lookupLogger = new EventsLogger();
ephemerisSegmentPropagator.addEventDetector(lookupLogger.monitorDetector(elevationDetector));
final EventsLogger referenceLogger = new EventsLogger();
propagator.clearEventsDetectors();
propagator.addEventDetector(referenceLogger.monitorDetector(elevationDetector));
propagator.propagate(segment.getStart(), segment.getStop());
ephemerisSegmentPropagator.propagate(segment.getStart(), segment.getStop());
final double dateEpsilon = 1.0e-9;
assertTrue(referenceLogger.getLoggedEvents().size() > 0);
assertEquals(referenceLogger.getLoggedEvents().size(), lookupLogger.getLoggedEvents().size());
for (int i = 0; i < referenceLogger.getLoggedEvents().size(); i++) {
LoggedEvent reference = referenceLogger.getLoggedEvents().get(i);
LoggedEvent actual = lookupLogger.getLoggedEvents().get(i);
assertEquals(0.0, FastMath.abs(reference.getState().getDate().durationFrom(actual.getState().getDate())), dateEpsilon);
}
final Propagator embeddedPropagator = segment.getPropagator();
final EventsLogger embeddedPropLogger = new EventsLogger();
embeddedPropagator.addEventDetector(embeddedPropLogger.monitorDetector(elevationDetector));
embeddedPropagator.propagate(segment.getStart(), segment.getStop());
assertEquals(referenceLogger.getLoggedEvents().size(), embeddedPropLogger.getLoggedEvents().size());
for (int i = 0; i < referenceLogger.getLoggedEvents().size(); i++) {
LoggedEvent reference = referenceLogger.getLoggedEvents().get(i);
LoggedEvent actual = embeddedPropLogger.getLoggedEvents().get(i);
assertEquals(0.0, FastMath.abs(reference.getState().getDate().durationFrom(actual.getState().getDate())), dateEpsilon);
}
final List<SpacecraftState> readInStates = new ArrayList<SpacecraftState>();
segment.getCoordinates().forEach(c -> {
try {
readInStates.add(new SpacecraftState(new CartesianOrbit(c, frame, mu)));
} catch (IllegalArgumentException | OrekitException e) {
fail(e.getLocalizedMessage());
}
});
final int interpolationPoints = 5;
Ephemeris directEphemProp = new Ephemeris(readInStates, interpolationPoints);
final EventsLogger directEphemPropLogger = new EventsLogger();
directEphemProp.addEventDetector(directEphemPropLogger.monitorDetector(elevationDetector));
directEphemProp.propagate(segment.getStart(), segment.getStop());
assertEquals(referenceLogger.getLoggedEvents().size(), directEphemPropLogger.getLoggedEvents().size());
for (int i = 0; i < referenceLogger.getLoggedEvents().size(); i++) {
LoggedEvent reference = referenceLogger.getLoggedEvents().get(i);
LoggedEvent actual = directEphemPropLogger.getLoggedEvents().get(i);
assertEquals(0.0, FastMath.abs(reference.getState().getDate().durationFrom(actual.getState().getDate())), dateEpsilon);
}
}
use of org.orekit.propagation.events.EventsLogger in project Orekit by CS-SI.
the class GroundFieldOfViewDetectorTest method testCaseSimilarToElevationDetector.
/**
* Check FoV detector is similar to {@link ElevationDetector} when using
* zenith pointing.
*
* @throws OrekitException on error.
*/
@Test
public void testCaseSimilarToElevationDetector() throws OrekitException {
// setup
double pi = FastMath.PI;
// arbitrary date
AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
AbsoluteDate endDate = date.shiftedBy(Constants.JULIAN_DAY);
Frame eci = FramesFactory.getGCRF();
Frame ecef = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, ecef);
GeodeticPoint gp = new GeodeticPoint(FastMath.toRadians(39), FastMath.toRadians(77), 0);
TopocentricFrame topo = new TopocentricFrame(earth, gp, "topo");
// iss like orbit
KeplerianOrbit orbit = new KeplerianOrbit(6378137 + 400e3, 0, FastMath.toRadians(51.65), 0, 0, 0, PositionAngle.TRUE, eci, date, Constants.EGM96_EARTH_MU);
Propagator prop = new KeplerianPropagator(orbit);
// compute expected result
ElevationDetector elevationDetector = new ElevationDetector(topo).withConstantElevation(pi / 6).withMaxCheck(5.0);
EventsLogger logger = new EventsLogger();
prop.addEventDetector(logger.monitorDetector(elevationDetector));
prop.propagate(endDate);
List<LoggedEvent> expected = logger.getLoggedEvents();
// action
// construct similar FoV based detector
// half width of 60 deg pointed along +Z in antenna frame
// not a perfect small circle b/c FoV makes a polygon with great circles
FieldOfView fov = new FieldOfView(Vector3D.PLUS_K, Vector3D.PLUS_I, pi / 3, 16, 0);
// simple case for fixed pointing to be similar to elevation detector.
// could define new frame with varying rotation for slewing antenna.
GroundFieldOfViewDetector fovDetector = new GroundFieldOfViewDetector(topo, fov).withMaxCheck(5.0);
Assert.assertSame(topo, fovDetector.getFrame());
Assert.assertSame(fov, fovDetector.getFieldOfView());
logger = new EventsLogger();
prop = new KeplerianPropagator(orbit);
prop.addEventDetector(logger.monitorDetector(fovDetector));
prop.propagate(endDate);
List<LoggedEvent> actual = logger.getLoggedEvents();
// verify
Assert.assertEquals(2, expected.size());
Assert.assertEquals(2, actual.size());
for (int i = 0; i < 2; i++) {
AbsoluteDate expectedDate = expected.get(i).getState().getDate();
AbsoluteDate actualDate = actual.get(i).getState().getDate();
// same event times to within 1s.
Assert.assertEquals(expectedDate.durationFrom(actualDate), 0.0, 1.0);
}
}
use of org.orekit.propagation.events.EventsLogger 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.EventsLogger 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());
}
Aggregations