/* Copyright 2002-2017 CS Systèmes d'Information * Licensed to CS Systèmes d'Information (CS) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * CS licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.orekit.propagation.analytical; import org.hipparchus.RealFieldElement; import org.hipparchus.util.MathArrays; import org.orekit.attitudes.FieldAttitudeProvider; import org.orekit.attitudes.FieldInertialProvider; import org.orekit.errors.OrekitException; import org.orekit.orbits.FieldOrbit; import org.orekit.orbits.OrbitType; import org.orekit.orbits.PositionAngle; import org.orekit.propagation.FieldSpacecraftState; import org.orekit.time.FieldAbsoluteDate; import org.orekit.utils.FieldTimeSpanMap; /** Simple Keplerian orbit propagator. * @see FieldOrbit * @author Guylaine Prat */ public class FieldKeplerianPropagator<T extends RealFieldElement<T>> extends FieldAbstractAnalyticalPropagator<T> { /** Initial state. */ private FieldSpacecraftState<T> initialState; /** All states. */ private transient FieldTimeSpanMap<FieldSpacecraftState<T>, T> states; /** Build a propagator from orbit only. * <p>The central attraction coefficient μ is set to the same value used * for the initial orbit definition. Mass and attitude provider are set to * unspecified non-null arbitrary values.</p> * @param initialFieldOrbit initial orbit * @exception OrekitException if initial attitude cannot be computed */ public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit) throws OrekitException { this(initialFieldOrbit, new FieldInertialProvider<T>(initialFieldOrbit.getA().getField()), initialFieldOrbit.getMu(), initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS)); } /** Build a propagator from orbit and central attraction coefficient μ. * <p>Mass and attitude provider are set to unspecified non-null arbitrary values.</p> * @param initialFieldOrbit initial orbit * @param mu central attraction coefficient (m³/s²) * @exception OrekitException if initial attitude cannot be computed */ public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit, final double mu) throws OrekitException { this(initialFieldOrbit, new FieldInertialProvider<T>(initialFieldOrbit.getA().getField()), mu, initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS)); } /** Build a propagator from orbit and attitude provider. * <p>The central attraction coefficient μ is set to the same value * used for the initial orbit definition. Mass is set to an unspecified * non-null arbitrary value.</p> * @param initialFieldOrbit initial orbit * @param attitudeProv attitude provider * @exception OrekitException if initial attitude cannot be computed */ public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit, final FieldAttitudeProvider<T> attitudeProv) throws OrekitException { this(initialFieldOrbit, attitudeProv, initialFieldOrbit.getMu(), initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS)); } /** Build a propagator from orbit, attitude provider and central attraction * coefficient μ. * <p>Mass is set to an unspecified non-null arbitrary value.</p> * @param initialFieldOrbit initial orbit * @param attitudeProv attitude provider * @param mu central attraction coefficient (m³/s²) * @exception OrekitException if initial attitude cannot be computed */ public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit, final FieldAttitudeProvider<T> attitudeProv, final double mu) throws OrekitException { this(initialFieldOrbit, attitudeProv, mu, initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS)); } /** Build propagator from orbit, attitude provider, central attraction * coefficient μ and mass. * @param initialFieldOrbit initial orbit * @param attitudeProv attitude provider * @param mu central attraction coefficient (m³/s²) * @param mass spacecraft mass (kg) * @exception OrekitException if initial attitude cannot be computed */ public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit, final FieldAttitudeProvider<T> attitudeProv, final double mu, final T mass) throws OrekitException { super(initialFieldOrbit.getA().getField(), attitudeProv); try { // ensure the orbit use the specified mu final OrbitType type = initialFieldOrbit.getType(); final T[] stateVector = MathArrays.buildArray(initialFieldOrbit.getA().getField(), 6); type.mapOrbitToArray(initialFieldOrbit, PositionAngle.TRUE, stateVector); final FieldOrbit<T> orbit = type.mapArrayToOrbit(stateVector, PositionAngle.TRUE, initialFieldOrbit.getDate(), mu, initialFieldOrbit.getFrame()); resetInitialState(new FieldSpacecraftState<T>(orbit, super.getAttitudeProvider().getAttitude(orbit, orbit.getDate(), orbit.getFrame()), mass)); } catch (OrekitException oe) { throw new OrekitException(oe); } } /** {@inheritDoc} */ public void resetInitialState(final FieldSpacecraftState<T> state) throws OrekitException { super.resetInitialState(state); initialState = state; states = new FieldTimeSpanMap<FieldSpacecraftState<T>, T>(initialState, state.getA().getField()); } /** {@inheritDoc} */ protected void resetIntermediateState(final FieldSpacecraftState<T> state, final boolean forward) throws OrekitException { // super.resetIntermediateState(state, forward); if (forward) { states.addValidAfter(state, state.getDate()); } else { states.addValidBefore(state, state.getDate()); } } /** {@inheritDoc} */ protected FieldOrbit<T> propagateOrbit(final FieldAbsoluteDate<T> date) throws OrekitException { // propagate orbit FieldOrbit<T> orbit = states.get(date).getOrbit(); do { // we use a loop here to compensate for very small date shifts error // that occur with long propagation time orbit = orbit.shiftedBy(date.durationFrom(orbit.getDate())); } while (!date.equals(orbit.getDate())); return orbit; } /** {@inheritDoc}*/ protected T getMass(final FieldAbsoluteDate<T> date) { return states.get(date).getMass(); } }