use of org.orekit.propagation.events.handlers.EventHandler.Action in project Orekit by CS-SI.
the class AbstractAnalyticalPropagator method acceptStep.
/**
* Accept a step, triggering events and step handlers.
* @param interpolator interpolator for the current step
* @param target final propagation time
* @param epsilon threshold for end date detection
* @return state at the end of the step
* @exception OrekitException if the switching function cannot be evaluated
* @exception MathRuntimeException if an event cannot be located
*/
protected SpacecraftState acceptStep(final OrekitStepInterpolator interpolator, final AbsoluteDate target, final double epsilon) throws OrekitException, MathRuntimeException {
SpacecraftState previous = interpolator.getPreviousState();
final SpacecraftState current = interpolator.getCurrentState();
// initialize the events states if needed
if (!statesInitialized) {
if (!eventsStates.isEmpty()) {
// initialize the events states
for (final EventState<?> state : eventsStates) {
state.reinitializeBegin(interpolator);
}
}
statesInitialized = true;
}
// search for next events that may occur during the step
final int orderingSign = interpolator.isForward() ? +1 : -1;
final Queue<EventState<?>> occurringEvents = new PriorityQueue<>(new Comparator<EventState<?>>() {
/**
* {@inheritDoc}
*/
@Override
public int compare(final EventState<?> es0, final EventState<?> es1) {
return orderingSign * es0.getEventDate().compareTo(es1.getEventDate());
}
});
for (final EventState<?> state : eventsStates) {
if (state.evaluateStep(interpolator)) {
// the event occurs during the current step
occurringEvents.add(state);
}
}
OrekitStepInterpolator restricted = interpolator;
do {
eventLoop: while (!occurringEvents.isEmpty()) {
// handle the chronologically first event
final EventState<?> currentEvent = occurringEvents.poll();
// get state at event time
SpacecraftState eventState = restricted.getInterpolatedState(currentEvent.getEventDate());
// try to advance all event states to current time
for (final EventState<?> state : eventsStates) {
if (state != currentEvent && state.tryAdvance(eventState, interpolator)) {
// we need to handle another event first
// remove event we just updated to prevent heap corruption
occurringEvents.remove(state);
// add it back to update its position in the heap
occurringEvents.add(state);
// re-queue the event we were processing
occurringEvents.add(currentEvent);
continue eventLoop;
}
}
// all event detectors agree we can advance to the current event time
final EventOccurrence occurrence = currentEvent.doEvent(eventState);
final Action action = occurrence.getAction();
isLastStep = action == Action.STOP;
if (isLastStep) {
// ensure the event is after the root if it is returned STOP
// this lets the user integrate to a STOP event and then restart
// integration from the same time.
eventState = interpolator.getInterpolatedState(occurrence.getStopDate());
restricted = restricted.restrictStep(previous, eventState);
}
// handle the first part of the step, up to the event
if (getStepHandler() != null) {
getStepHandler().handleStep(restricted, isLastStep);
}
if (isLastStep) {
// the event asked to stop integration
return eventState;
}
if (action == Action.RESET_DERIVATIVES || action == Action.RESET_STATE) {
// some event handler has triggered changes that
// invalidate the derivatives, we need to recompute them
final SpacecraftState resetState = occurrence.getNewState();
if (resetState != null) {
resetIntermediateState(resetState, interpolator.isForward());
return resetState;
}
}
// at this point we know action == Action.CONTINUE
// prepare handling of the remaining part of the step
previous = eventState;
restricted = new BasicStepInterpolator(restricted.isForward(), eventState, current);
// check if the same event occurs again in the remaining part of the step
if (currentEvent.evaluateStep(restricted)) {
// the event occurs during the current step
occurringEvents.add(currentEvent);
}
}
// another event detector.
for (final EventState<?> state : eventsStates) {
if (state.tryAdvance(current, interpolator)) {
occurringEvents.add(state);
}
}
} while (!occurringEvents.isEmpty());
isLastStep = target.equals(current.getDate());
// handle the remaining part of the step, after all events if any
if (getStepHandler() != null) {
getStepHandler().handleStep(interpolator, isLastStep);
}
return current;
}
use of org.orekit.propagation.events.handlers.EventHandler.Action in project Orekit by CS-SI.
the class CloseEventsAbstractTest method testEventChangesGFunctionDefinition.
/**
* test when one event detector changes the definition of another's g function before
* the end of the step as a result of a continue action. Not sure if this should be
* officially supported, but it is used in Orekit's DateDetector, it's useful, and not
* too hard to implement.
*/
@Test
public void testEventChangesGFunctionDefinition() throws OrekitException {
// setup
double maxCheck = 5;
double tolerance = 1e-6;
double t1 = 11, t2 = 19;
// shared event list so we know the order in which they occurred
List<Event<EventDetector>> events = new ArrayList<>();
// mutable boolean
boolean[] swap = new boolean[1];
final ContinuousDetector detectorA = new ContinuousDetector(t1).withThreshold(maxCheck).withThreshold(tolerance).withHandler(new RecordAndContinue<EventDetector>(events) {
@Override
public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
swap[0] = true;
return super.eventOccurred(s, detector, increasing);
}
});
ContinuousDetector detectorB = new ContinuousDetector(t2);
EventDetector detectorC = new AbstractDetector<EventDetector>(maxCheck, tolerance, 100, new RecordAndContinue<>(events)) {
private static final long serialVersionUID = 1L;
@Override
public double g(SpacecraftState s) throws OrekitException {
if (swap[0]) {
return detectorB.g(s);
} else {
return -1;
}
}
@Override
protected EventDetector create(double newMaxCheck, double newThreshold, int newMaxIter, EventHandler<? super EventDetector> newHandler) {
return null;
}
};
Propagator propagator = getPropagator(10);
propagator.addEventDetector(detectorA);
propagator.addEventDetector(detectorC);
// action
propagator.propagate(epoch.shiftedBy(30));
// verify
Assert.assertEquals(2, events.size());
Assert.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch), tolerance);
Assert.assertEquals(true, events.get(0).isIncreasing());
Assert.assertSame(detectorA, events.get(0).getDetector());
Assert.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch), tolerance);
Assert.assertEquals(true, events.get(1).isIncreasing());
Assert.assertSame(detectorC, events.get(1).getDetector());
}
use of org.orekit.propagation.events.handlers.EventHandler.Action in project Orekit by CS-SI.
the class CloseEventsAbstractTest method testEventChangesGFunctionDefinitionReverse.
/**
* test when one event detector changes the definition of another's g function before
* the end of the step as a result of a continue action. Not sure if this should be
* officially supported, but it is used in Orekit's DateDetector, it's useful, and not
* too hard to implement.
*/
@Test
public void testEventChangesGFunctionDefinitionReverse() throws OrekitException {
// setup
double maxCheck = 5;
double tolerance = 1e-6;
double t1 = -11, t2 = -19;
// shared event list so we know the order in which they occurred
List<Event<EventDetector>> events = new ArrayList<>();
// mutable boolean
boolean[] swap = new boolean[1];
ContinuousDetector detectorA = new ContinuousDetector(t1).withMaxCheck(maxCheck).withThreshold(tolerance).withHandler(new RecordAndContinue<EventDetector>(events) {
@Override
public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
swap[0] = true;
return super.eventOccurred(s, detector, increasing);
}
});
ContinuousDetector detectorB = new ContinuousDetector(t2);
EventDetector detectorC = new AbstractDetector<EventDetector>(maxCheck, tolerance, 100, new RecordAndContinue<>(events)) {
private static final long serialVersionUID = 1L;
@Override
public double g(SpacecraftState state) throws OrekitException {
if (swap[0]) {
return detectorB.g(state);
} else {
return 1;
}
}
@Override
protected EventDetector create(double newMaxCheck, double newThreshold, int newMaxIter, EventHandler<? super EventDetector> newHandler) {
return null;
}
};
Propagator propagator = getPropagator(10);
propagator.addEventDetector(detectorA);
propagator.addEventDetector(detectorC);
// action
propagator.propagate(epoch.shiftedBy(-30.0));
// verify
Assert.assertEquals(2, events.size());
Assert.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch), tolerance);
Assert.assertEquals(true, events.get(0).isIncreasing());
Assert.assertSame(detectorA, events.get(0).getDetector());
Assert.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch), tolerance);
Assert.assertEquals(true, events.get(1).isIncreasing());
Assert.assertSame(detectorC, events.get(1).getDetector());
}
use of org.orekit.propagation.events.handlers.EventHandler.Action in project Orekit by CS-SI.
the class FunctionalDetectorTest method testFunctionalDetector.
/**
* Check {@link FunctionalDetector}.
*
* @throws OrekitException on error.
*/
@Test
public void testFunctionalDetector() throws OrekitException {
// setup
GFunction g = SpacecraftState::getMass;
EventHandler<EventDetector> handler = (s, detector, increasing) -> Action.STOP;
// action
FunctionalDetector detector = new FunctionalDetector().withMaxIter(1).withThreshold(2).withMaxCheck(3).withGFunction(g).withHandler(handler);
// verify
MatcherAssert.assertThat(detector.getMaxIterationCount(), CoreMatchers.is(1));
MatcherAssert.assertThat(detector.getThreshold(), CoreMatchers.is(2.0));
MatcherAssert.assertThat(detector.getMaxCheckInterval(), CoreMatchers.is(3.0));
MatcherAssert.assertThat(detector.getHandler(), CoreMatchers.is(handler));
MatcherAssert.assertThat(detector.getGFunction(), CoreMatchers.is(g));
SpacecraftState state = new SpacecraftState(new CartesianOrbit(new PVCoordinates(new Vector3D(1, 2, 3), new Vector3D(4, 5, 6)), FramesFactory.getGCRF(), AbsoluteDate.CCSDS_EPOCH, 4), 5);
MatcherAssert.assertThat(detector.g(state), CoreMatchers.is(5.0));
MatcherAssert.assertThat(detector.eventOccurred(null, false), CoreMatchers.is(Action.STOP));
}
Aggregations