use of org.orekit.propagation.SpacecraftState in project Orekit by CS-SI.
the class KeplerianPropagator method writeReplace.
/**
* Replace the instance with a data transfer object for serialization.
* @return data transfer object that will be serialized
* @exception NotSerializableException if an additional state provider is not serializable
*/
private Object writeReplace() throws NotSerializableException {
try {
// managed states providers
final List<AdditionalStateProvider> serializableProviders = new ArrayList<AdditionalStateProvider>();
for (final AdditionalStateProvider provider : getAdditionalStateProviders()) {
if (provider instanceof Serializable) {
serializableProviders.add(provider);
} else {
throw new NotSerializableException(provider.getClass().getName());
}
}
// states transitions
final AbsoluteDate[] transitionDates;
final SpacecraftState[] allStates;
final SortedSet<TimeSpanMap.Transition<SpacecraftState>> transitions = states.getTransitions();
if (transitions.size() == 1 && transitions.first().getBefore() == transitions.first().getAfter()) {
// the single entry is a dummy one, without a real transition
// we ignore it completely
transitionDates = null;
allStates = null;
} else {
transitionDates = new AbsoluteDate[transitions.size()];
allStates = new SpacecraftState[transitions.size() + 1];
int i = 0;
for (final TimeSpanMap.Transition<SpacecraftState> transition : transitions) {
if (i == 0) {
// state before the first transition
allStates[i] = transition.getBefore();
}
transitionDates[i] = transition.getDate();
allStates[++i] = transition.getAfter();
}
}
return new DataTransferObject(getInitialState().getOrbit(), getAttitudeProvider(), getInitialState().getMu(), getInitialState().getMass(), transitionDates, allStates, serializableProviders.toArray(new AdditionalStateProvider[serializableProviders.size()]));
} catch (OrekitException orekitException) {
// this should never happen
throw new OrekitInternalError(null);
}
}
use of org.orekit.propagation.SpacecraftState 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.SpacecraftState in project Orekit by CS-SI.
the class DSSTPropagator method computeOsculatingState.
/**
* Conversion from mean to osculating orbit.
* <p>
* Compute osculating state <b>in a DSST sense</b>, corresponding to the
* mean SpacecraftState in input, and according to the Force models taken
* into account.
* </p><p>
* Since the osculating state is obtained by adding short-periodic variation
* of each force model, the resulting output will depend on the
* force models parameterized in input.
* </p>
* @param mean Mean state to convert
* @param forces Forces to take into account
* @param attitudeProvider attitude provider (may be null if there are no Gaussian force models
* like atmospheric drag, radiation pressure or specific user-defined models)
* @return osculating state in a DSST sense
* @throws OrekitException if computation of short periodics fails
*/
public static SpacecraftState computeOsculatingState(final SpacecraftState mean, final AttitudeProvider attitudeProvider, final Collection<DSSTForceModel> forces) throws OrekitException {
// Create the auxiliary object
final AuxiliaryElements aux = new AuxiliaryElements(mean.getOrbit(), I);
// Set the force models
final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<ShortPeriodTerms>();
for (final DSSTForceModel force : forces) {
force.registerAttitudeProvider(attitudeProvider);
shortPeriodTerms.addAll(force.initialize(aux, false));
force.updateShortPeriodTerms(mean);
}
final EquinoctialOrbit osculatingOrbit = computeOsculatingOrbit(mean, shortPeriodTerms);
return new SpacecraftState(osculatingOrbit, mean.getAttitude(), mean.getMass(), mean.getAdditionalStates());
}
use of org.orekit.propagation.SpacecraftState in project Orekit by CS-SI.
the class EventState method evaluateStep.
/**
* Evaluate the impact of the proposed step on the event detector.
* @param interpolator step interpolator for the proposed step
* @return true if the event detector triggers an event before
* the end of the proposed step (this implies the step should be
* rejected)
* @exception OrekitException if the switching function
* cannot be evaluated
* @exception MathRuntimeException if an event cannot be located
*/
public boolean evaluateStep(final OrekitStepInterpolator interpolator) throws OrekitException, MathRuntimeException {
forward = interpolator.isForward();
final SpacecraftState s1 = interpolator.getCurrentState();
final AbsoluteDate t1 = s1.getDate();
final double dt = t1.durationFrom(t0);
if (FastMath.abs(dt) < detector.getThreshold()) {
// we cannot do anything on such a small step, don't trigger any events
return false;
}
// number of points to check in the current step
final int n = FastMath.max(1, (int) FastMath.ceil(FastMath.abs(dt) / detector.getMaxCheckInterval()));
final double h = dt / n;
AbsoluteDate ta = t0;
double ga = g0;
for (int i = 0; i < n; ++i) {
// evaluate handler value at the end of the substep
final AbsoluteDate tb = (i == n - 1) ? t1 : t0.shiftedBy((i + 1) * h);
final double gb = g(interpolator.getInterpolatedState(tb));
// check events occurrence
if (gb == 0.0 || (g0Positive ^ (gb > 0))) {
// there is a sign change: an event is expected during this step
if (findRoot(interpolator, ta, ga, tb, gb)) {
return true;
}
} else {
// no sign change: there is no event for now
ta = tb;
ga = gb;
}
}
// no event during the whole step
pendingEvent = false;
pendingEventTime = null;
return false;
}
use of org.orekit.propagation.SpacecraftState in project Orekit by CS-SI.
the class EventState method doEvent.
/**
* Notify the user's listener of the event. The event occurs wholly within this method
* call including a call to {@link EventDetector#resetState(SpacecraftState)}
* if necessary.
*
* @param state the state at the time of the event. This must be at the same time as
* the current value of {@link #getEventDate()}.
* @return the user's requested action and the new state if the action is {@link
* org.orekit.propagation.events.handlers.EventHandler.Action#RESET_STATE Action.RESET_STATE}.
* Otherwise the new state is {@code state}. The stop time indicates what time propagation
* should stop if the action is {@link
* org.orekit.propagation.events.handlers.EventHandler.Action#STOP Action.STOP}.
* This guarantees the integration will stop on or after the root, so that integration
* may be restarted safely.
* @exception OrekitException if the event detector throws one
*/
public EventOccurrence doEvent(final SpacecraftState state) throws OrekitException {
// check event is pending and is at the same time
check(pendingEvent);
check(state.getDate().equals(this.pendingEventTime));
final EventHandler.Action action = detector.eventOccurred(state, increasing == forward);
final SpacecraftState newState;
if (action == EventHandler.Action.RESET_STATE) {
newState = detector.resetState(state);
} else {
newState = state;
}
// clear pending event
pendingEvent = false;
pendingEventTime = null;
// setup for next search
earliestTimeConsidered = afterEvent;
t0 = afterEvent;
g0 = afterG;
g0Positive = increasing;
// check g0Positive set correctly
check(g0 == 0.0 || g0Positive == (g0 > 0));
return new EventOccurrence(action, newState, stopTime);
}
Aggregations