KeplerianPropagator.java

  1. /* Copyright 2002-2020 CS GROUP
  2.  * Licensed to CS GROUP (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 java.util.Collections;
  19. import java.util.Map;

  20. import org.orekit.annotation.DefaultDataContext;
  21. import org.orekit.attitudes.Attitude;
  22. import org.orekit.attitudes.AttitudeProvider;
  23. import org.orekit.data.DataContext;
  24. import org.orekit.orbits.Orbit;
  25. import org.orekit.orbits.OrbitType;
  26. import org.orekit.orbits.PositionAngle;
  27. import org.orekit.propagation.Propagator;
  28. import org.orekit.propagation.SpacecraftState;
  29. import org.orekit.time.AbsoluteDate;
  30. import org.orekit.utils.TimeSpanMap;

  31. /** Simple Keplerian orbit propagator.
  32.  * @see Orbit
  33.  * @author Guylaine Prat
  34.  */
  35. public class KeplerianPropagator extends AbstractAnalyticalPropagator {

  36.     /** Initial state. */
  37.     private SpacecraftState initialState;

  38.     /** All states. */
  39.     private TimeSpanMap<SpacecraftState> states;

  40.     /** Build a propagator from orbit only.
  41.      * <p>The central attraction coefficient μ is set to the same value used
  42.      * for the initial orbit definition. Mass and attitude provider are set to
  43.      * unspecified non-null arbitrary values.</p>
  44.      *
  45.      * <p>This constructor uses the {@link DataContext#getDefault() default data context}.
  46.      *
  47.      * @param initialOrbit initial orbit
  48.      * @see #KeplerianPropagator(Orbit, AttitudeProvider)
  49.      */
  50.     @DefaultDataContext
  51.     public KeplerianPropagator(final Orbit initialOrbit) {
  52.         this(initialOrbit, Propagator.getDefaultLaw(DataContext.getDefault().getFrames()),
  53.                 initialOrbit.getMu(), DEFAULT_MASS);
  54.     }

  55.     /** Build a propagator from orbit and central attraction coefficient μ.
  56.      * <p>Mass and attitude provider are set to unspecified non-null arbitrary values.</p>
  57.      *
  58.      * <p>This constructor uses the {@link DataContext#getDefault() default data context}.
  59.      *
  60.      * @param initialOrbit initial orbit
  61.      * @param mu central attraction coefficient (m³/s²)
  62.      * @see #KeplerianPropagator(Orbit, AttitudeProvider, double)
  63.      */
  64.     @DefaultDataContext
  65.     public KeplerianPropagator(final Orbit initialOrbit, final double mu) {
  66.         this(initialOrbit, Propagator.getDefaultLaw(DataContext.getDefault().getFrames()),
  67.                 mu, DEFAULT_MASS);
  68.     }

  69.     /** Build a propagator from orbit and attitude provider.
  70.      * <p>The central attraction coefficient μ is set to the same value
  71.      * used for the initial orbit definition. Mass is set to an unspecified
  72.      * non-null arbitrary value.</p>
  73.      * @param initialOrbit initial orbit
  74.      * @param attitudeProv  attitude provider
  75.      */
  76.     public KeplerianPropagator(final Orbit initialOrbit,
  77.                                final AttitudeProvider attitudeProv) {
  78.         this(initialOrbit, attitudeProv, initialOrbit.getMu(), DEFAULT_MASS);
  79.     }

  80.     /** Build a propagator from orbit, attitude provider and central attraction
  81.      * coefficient μ.
  82.      * <p>Mass is set to an unspecified non-null arbitrary value.</p>
  83.      * @param initialOrbit initial orbit
  84.      * @param attitudeProv attitude provider
  85.      * @param mu central attraction coefficient (m³/s²)
  86.      */
  87.     public KeplerianPropagator(final Orbit initialOrbit,
  88.                                final AttitudeProvider attitudeProv,
  89.                                final double mu) {
  90.         this(initialOrbit, attitudeProv, mu, DEFAULT_MASS);
  91.     }

  92.     /** Build propagator from orbit, attitude provider, central attraction
  93.      * coefficient μ and mass.
  94.      * @param initialOrbit initial orbit
  95.      * @param attitudeProv attitude provider
  96.      * @param mu central attraction coefficient (m³/s²)
  97.      * @param mass spacecraft mass (kg)
  98.      */
  99.     public KeplerianPropagator(final Orbit initialOrbit, final AttitudeProvider attitudeProv,
  100.                                final double mu, final double mass) {

  101.         super(attitudeProv);

  102.         // ensure the orbit use the specified mu and has no non-Keplerian derivatives
  103.         initialState = fixState(initialOrbit,
  104.                                 getAttitudeProvider().getAttitude(initialOrbit,
  105.                                                                   initialOrbit.getDate(),
  106.                                                                   initialOrbit.getFrame()),
  107.                                 mass, mu, Collections.emptyMap());
  108.         states = new TimeSpanMap<SpacecraftState>(initialState);
  109.         super.resetInitialState(initialState);

  110.     }

  111.     /** Fix state to use a specified mu and remove derivatives.
  112.      * <p>
  113.      * This ensures the propagation model (which is based on calling
  114.      * {@link Orbit#shiftedBy(double)}) is Keplerian only and uses a specified mu.
  115.      * </p>
  116.      * @param orbit orbit to fix
  117.      * @param attitude current attitude
  118.      * @param mass current mass
  119.      * @param mu gravity coefficient to use
  120.      * @param additionalStates additional states
  121.      * @return fixed orbit
  122.      */
  123.     private SpacecraftState fixState(final Orbit orbit, final Attitude attitude, final double mass,
  124.                                      final double mu, final Map<String, double[]> additionalStates) {
  125.         final OrbitType type = orbit.getType();
  126.         final double[] stateVector = new double[6];
  127.         type.mapOrbitToArray(orbit, PositionAngle.TRUE, stateVector, null);
  128.         final Orbit fixedOrbit = type.mapArrayToOrbit(stateVector, null, PositionAngle.TRUE,
  129.                                                       orbit.getDate(), mu, orbit.getFrame());
  130.         SpacecraftState fixedState = new SpacecraftState(fixedOrbit, attitude, mass);
  131.         for (final Map.Entry<String, double[]> entry : additionalStates.entrySet()) {
  132.             fixedState = fixedState.addAdditionalState(entry.getKey(), entry.getValue());
  133.         }
  134.         return fixedState;
  135.     }

  136.     /** {@inheritDoc} */
  137.     public void resetInitialState(final SpacecraftState state) {

  138.         // ensure the orbit use the specified mu and has no non-Keplerian derivatives
  139.         final double mu = initialState == null ? state.getMu() : initialState.getMu();
  140.         final SpacecraftState fixedState = fixState(state.getOrbit(),
  141.                                                     state.getAttitude(),
  142.                                                     state.getMass(),
  143.                                                     mu,
  144.                                                     state.getAdditionalStates());

  145.         initialState = fixedState;
  146.         states       = new TimeSpanMap<SpacecraftState>(initialState);
  147.         super.resetInitialState(fixedState);

  148.     }

  149.     /** {@inheritDoc} */
  150.     protected void resetIntermediateState(final SpacecraftState state, final boolean forward) {
  151.         if (forward) {
  152.             states.addValidAfter(state, state.getDate());
  153.         } else {
  154.             states.addValidBefore(state, state.getDate());
  155.         }
  156.         stateChanged(state);
  157.     }

  158.     /** {@inheritDoc} */
  159.     protected Orbit propagateOrbit(final AbsoluteDate date) {

  160.         // propagate orbit
  161.         Orbit orbit = states.get(date).getOrbit();
  162.         do {
  163.             // we use a loop here to compensate for very small date shifts error
  164.             // that occur with long propagation time
  165.             orbit = orbit.shiftedBy(date.durationFrom(orbit.getDate()));
  166.         } while (!date.equals(orbit.getDate()));

  167.         return orbit;

  168.     }

  169.     /** {@inheritDoc}*/
  170.     protected double getMass(final AbsoluteDate date) {
  171.         return states.get(date).getMass();
  172.     }

  173. }