FieldKeplerianPropagator.java

  1. /* Copyright 2002-2018 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.propagation.analytical;


  18. import org.hipparchus.RealFieldElement;
  19. import org.hipparchus.util.MathArrays;
  20. import org.orekit.attitudes.AttitudeProvider;
  21. import org.orekit.attitudes.FieldAttitude;
  22. import org.orekit.errors.OrekitException;
  23. import org.orekit.orbits.FieldOrbit;
  24. import org.orekit.orbits.Orbit;
  25. import org.orekit.orbits.OrbitType;
  26. import org.orekit.orbits.PositionAngle;
  27. import org.orekit.propagation.FieldSpacecraftState;
  28. import org.orekit.time.FieldAbsoluteDate;
  29. import org.orekit.utils.FieldTimeSpanMap;

  30. /** Simple Keplerian orbit propagator.
  31.  * @see FieldOrbit
  32.  * @author Guylaine Prat
  33.  */
  34. public class FieldKeplerianPropagator<T extends RealFieldElement<T>> extends FieldAbstractAnalyticalPropagator<T> {


  35.     /** Initial state. */
  36.     private FieldSpacecraftState<T> initialState;

  37.     /** All states. */
  38.     private transient FieldTimeSpanMap<FieldSpacecraftState<T>, T> states;

  39.     /** Build a propagator from orbit only.
  40.      * <p>The central attraction coefficient μ is set to the same value used
  41.      * for the initial orbit definition. Mass and attitude provider are set to
  42.      * unspecified non-null arbitrary values.</p>
  43.      * @param initialFieldOrbit initial orbit
  44.      * @exception OrekitException if initial attitude cannot be computed
  45.      */
  46.     public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit)
  47.         throws OrekitException {
  48.         this(initialFieldOrbit, DEFAULT_LAW, initialFieldOrbit.getMu(), initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS));
  49.     }

  50.     /** Build a propagator from orbit and central attraction coefficient μ.
  51.      * <p>Mass and attitude provider are set to unspecified non-null arbitrary values.</p>
  52.      * @param initialFieldOrbit initial orbit
  53.      * @param mu central attraction coefficient (m³/s²)
  54.      * @exception OrekitException if initial attitude cannot be computed
  55.      */
  56.     public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit, final double mu)
  57.         throws OrekitException {
  58.         this(initialFieldOrbit, DEFAULT_LAW, mu, initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS));
  59.     }

  60.     /** Build a propagator from orbit and attitude provider.
  61.      * <p>The central attraction coefficient μ is set to the same value
  62.      * used for the initial orbit definition. Mass is set to an unspecified
  63.      * non-null arbitrary value.</p>
  64.      * @param initialFieldOrbit initial orbit
  65.      * @param attitudeProv  attitude provider
  66.      * @exception OrekitException if initial attitude cannot be computed
  67.      */
  68.     public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit,
  69.                                     final AttitudeProvider attitudeProv)
  70.         throws OrekitException {
  71.         this(initialFieldOrbit, attitudeProv, initialFieldOrbit.getMu(), initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS));
  72.     }

  73.     /** Build a propagator from orbit, attitude provider and central attraction
  74.      * coefficient μ.
  75.      * <p>Mass is set to an unspecified non-null arbitrary value.</p>
  76.      * @param initialFieldOrbit initial orbit
  77.      * @param attitudeProv attitude provider
  78.      * @param mu central attraction coefficient (m³/s²)
  79.      * @exception OrekitException if initial attitude cannot be computed
  80.      */
  81.     public FieldKeplerianPropagator(final FieldOrbit<T> initialFieldOrbit,
  82.                                     final AttitudeProvider attitudeProv,
  83.                                     final double mu)
  84.                                                     throws OrekitException {
  85.         this(initialFieldOrbit, attitudeProv, mu, initialFieldOrbit.getA().getField().getZero().add(DEFAULT_MASS));
  86.     }

  87.     /** Build propagator from orbit, attitude provider, central attraction
  88.      * coefficient μ and mass.
  89.      * @param initialOrbit initial orbit
  90.      * @param attitudeProv attitude provider
  91.      * @param mu central attraction coefficient (m³/s²)
  92.      * @param mass spacecraft mass (kg)
  93.      * @exception OrekitException if initial attitude cannot be computed
  94.      */
  95.     public FieldKeplerianPropagator(final FieldOrbit<T> initialOrbit, final AttitudeProvider attitudeProv,
  96.                                     final double mu, final T mass)
  97.         throws OrekitException {

  98.         super(initialOrbit.getA().getField(), attitudeProv);

  99.         // ensure the orbit use the specified mu and has no non-Keplerian derivatives
  100.         initialState = fixState(initialOrbit,
  101.                                 getAttitudeProvider().getAttitude(initialOrbit,
  102.                                                                   initialOrbit.getDate(),
  103.                                                                   initialOrbit.getFrame()),
  104.                                 mass, mu);
  105.         states = new FieldTimeSpanMap<>(initialState, initialOrbit.getA().getField());
  106.         super.resetInitialState(initialState);
  107.     }

  108.     /** Fix state to use a specified mu and remove derivatives.
  109.      * <p>
  110.      * This ensures the propagation model (which is based on calling
  111.      * {@link Orbit#shiftedBy(double)}) is Keplerian only and uses a specified mu.
  112.      * </p>
  113.      * @param orbit orbit to fix
  114.      * @param attitude current attitude
  115.      * @param mass current mass
  116.      * @param mu gravity coefficient to use
  117.      * @return fixed orbit
  118.      */
  119.     private FieldSpacecraftState<T> fixState(final FieldOrbit<T> orbit, final FieldAttitude<T> attitude, final T mass,
  120.                                      final double mu) {
  121.         final OrbitType type = orbit.getType();
  122.         final T[] stateVector = MathArrays.buildArray(mass.getField(), 6);
  123.         type.mapOrbitToArray(orbit, PositionAngle.TRUE, stateVector, null);
  124.         final FieldOrbit<T> fixedOrbit = type.mapArrayToOrbit(stateVector, null, PositionAngle.TRUE,
  125.                                                               orbit.getDate(), mu, orbit.getFrame());
  126.         return new FieldSpacecraftState<>(fixedOrbit, attitude, mass);
  127.     }

  128.     /** {@inheritDoc} */
  129.     public void resetInitialState(final FieldSpacecraftState<T> state)
  130.         throws OrekitException {

  131.         // ensure the orbit use the specified mu and has no non-Keplerian derivatives
  132.         final double mu = initialState == null ? state.getMu() : initialState.getMu();
  133.         final FieldSpacecraftState<T> fixedState = fixState(state.getOrbit(),
  134.                                                             state.getAttitude(),
  135.                                                             state.getMass(),
  136.                                                             mu);

  137.         initialState = fixedState;
  138.         states       = new FieldTimeSpanMap<>(initialState, state.getDate().getField());
  139.         super.resetInitialState(fixedState);

  140.     }

  141.     /** {@inheritDoc} */
  142.     protected void resetIntermediateState(final FieldSpacecraftState<T> state, final boolean forward)
  143.         throws OrekitException {
  144.         if (forward) {
  145.             states.addValidAfter(state, state.getDate());
  146.         } else {
  147.             states.addValidBefore(state, state.getDate());
  148.         }
  149.     }

  150.     /** {@inheritDoc} */
  151.     protected FieldOrbit<T> propagateOrbit(final FieldAbsoluteDate<T> date)
  152.         throws OrekitException {
  153.         // propagate orbit
  154.         FieldOrbit<T> orbit = states.get(date).getOrbit();
  155.         do {
  156.             // we use a loop here to compensate for very small date shifts error
  157.             // that occur with long propagation time
  158.             orbit = orbit.shiftedBy(date.durationFrom(orbit.getDate()));
  159.         } while (!date.equals(orbit.getDate()));
  160.         return orbit;
  161.     }

  162.     /** {@inheritDoc}*/
  163.     protected T getMass(final FieldAbsoluteDate<T> date) {
  164.         return states.get(date).getMass();
  165.     }

  166. }