EphemerisFile.java

  1. /* Contributed in the public domain.
  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.files.general;

  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import java.util.Map;

  21. import org.orekit.attitudes.AttitudeProvider;
  22. import org.orekit.attitudes.FrameAlignedProvider;
  23. import org.orekit.errors.OrekitException;
  24. import org.orekit.frames.Frame;
  25. import org.orekit.propagation.BoundedPropagator;
  26. import org.orekit.propagation.Propagator;
  27. import org.orekit.propagation.analytical.AggregateBoundedPropagator;
  28. import org.orekit.time.AbsoluteDate;
  29. import org.orekit.utils.CartesianDerivativesFilter;
  30. import org.orekit.utils.TimeStampedPVCoordinates;

  31. /**
  32.  * An interface for accessing the data stored in an ephemeris file and using the data to
  33.  * create a working {@link org.orekit.propagation.Propagator Propagator}.
  34.  *
  35.  * <p> An {@link EphemerisFile} consists of one or more satellites each with a unique ID
  36.  * within the file. The ephemeris for each satellite consists of one or more segments.
  37.  *
  38.  * <p> Some ephemeris file formats may supply additional information that is not available
  39.  * via this interface. In those cases it is recommended that the parser return a subclass
  40.  * of this interface to provide access to the additional information.
  41.  *
  42.  * @param <C> type of the Cartesian coordinates
  43.  * @param <S> type of the segment
  44.  * @author Evan Ward
  45.  * @see SatelliteEphemeris
  46.  * @see EphemerisSegment
  47.  */
  48. public interface EphemerisFile<C extends TimeStampedPVCoordinates,
  49.                                S extends EphemerisFile.EphemerisSegment<C>> {

  50.     /**
  51.      * Get the loaded ephemeris for each satellite in the file.
  52.      *
  53.      * @return a map from the satellite's ID to the information about that satellite
  54.      * contained in the file.
  55.      */
  56.     Map<String, ? extends SatelliteEphemeris<C, S>> getSatellites();

  57.     /**
  58.      * Contains the information about a single satellite from an {@link EphemerisFile}.
  59.      *
  60.      * <p> A satellite ephemeris consists of one or more {@link EphemerisSegment}s.
  61.      * Segments are typically used to split up an ephemeris at discontinuous events, such
  62.      * as a maneuver.
  63.      * @param <C> type of the Cartesian coordinates
  64.      * @param <S> type of the segment
  65.      * @author Evan Ward
  66.      * @see EphemerisFile
  67.      * @see EphemerisSegment
  68.      */
  69.     interface SatelliteEphemeris<C extends TimeStampedPVCoordinates,
  70.                                  S extends EphemerisSegment<C>> {

  71.         /**
  72.          * Get the satellite ID. The satellite ID is unique only within the same ephemeris
  73.          * file.
  74.          *
  75.          * @return the satellite's ID, never {@code null}.
  76.          */
  77.         String getId();

  78.         /**
  79.          * Get the standard gravitational parameter for the satellite.
  80.          *
  81.          * @return the gravitational parameter used in {@link #getPropagator(AttitudeProvider)}, in m³/s².
  82.          */
  83.         double getMu();

  84.         /**
  85.          * Get the segments of the ephemeris.
  86.          *
  87.          * <p> Ephemeris segments are typically used to split an ephemeris around
  88.          * discontinuous events, such as maneuvers.
  89.          *
  90.          * @return the segments contained in the ephemeris file for this satellite.
  91.          */
  92.         List<S> getSegments();

  93.         /**
  94.          * Get the start date of the ephemeris.
  95.          *
  96.          * <p> The date returned by this method is equivalent to {@code
  97.          * getPropagator().getMinDate()}.
  98.          *
  99.          * @return ephemeris start date.
  100.          */
  101.         AbsoluteDate getStart();

  102.         /**
  103.          * Get the end date of the ephemeris.
  104.          *
  105.          * <p> The date returned by this method is equivalent to {@code getPropagator().getMaxDate()}.
  106.          *
  107.          * @return ephemeris end date.
  108.          */
  109.         AbsoluteDate getStop();

  110.         /**
  111.          * View this ephemeris as a propagator, combining data from all {@link
  112.          * #getSegments() segments}.
  113.          *
  114.          * <p>
  115.          * In order to view the ephemeris for this satellite as a {@link Propagator}
  116.          * several conditions must be met. An Orekit {@link Frame} must be constructable
  117.          * from the frame specification in the ephemeris file. This condition is met when
  118.          * {@link EphemerisSegment#getFrame()} return normally for all {@link
  119.          * #getSegments() segments}. If there are multiple segments they must be adjacent
  120.          * such that there are no duplicates or gaps in the ephemeris. The definition of
  121.          * adjacent depends on the ephemeris format as some formats define usable start
  122.          * and stop times that are different from the ephemeris data start and stop times.
  123.          * If these conditions are not met an {@link OrekitException} may be thrown by
  124.          * this method or by one of the methods of the returned {@link Propagator}.
  125.          * </p>
  126.          * <p>
  127.          * The {@link AttitudeProvider attitude provider} used is a {@link FrameAlignedProvider}
  128.          * aligned with the {@link EphemerisSegment#getInertialFrame() inertial frame} from the first segment.
  129.          * </p>
  130.          *
  131.          * <p>Each call to this method creates a new propagator.</p>
  132.          *
  133.          * @return a propagator for all the data in this ephemeris file.
  134.          */
  135.         default BoundedPropagator getPropagator() {
  136.             return getPropagator(new FrameAlignedProvider(getSegments().get(0).getInertialFrame()));
  137.         }

  138.         /**
  139.          * View this ephemeris as a propagator, combining data from all {@link
  140.          * #getSegments() segments}.
  141.          *
  142.          * <p>
  143.          * In order to view the ephemeris for this satellite as a {@link Propagator}
  144.          * several conditions must be met. An Orekit {@link Frame} must be constructable
  145.          * from the frame specification in the ephemeris file. This condition is met when
  146.          * {@link EphemerisSegment#getFrame()} return normally for all {@link
  147.          * #getSegments() segments}. If there are multiple segments they must be adjacent
  148.          * such that there are no duplicates or gaps in the ephemeris. The definition of
  149.          * adjacent depends on the ephemeris format as some formats define usable start
  150.          * and stop times that are different from the ephemeris data start and stop times.
  151.          * If these conditions are not met an {@link OrekitException} may be thrown by
  152.          * this method or by one of the methods of the returned {@link Propagator}.
  153.          * </p>
  154.          *
  155.          * <p>Each call to this method creates a new propagator.</p>
  156.          *
  157.          * @param attitudeProvider provider for attitude computation
  158.          * @return a propagator for all the data in this ephemeris file.
  159.          * @since 12.0
  160.          */
  161.         default BoundedPropagator getPropagator(final  AttitudeProvider attitudeProvider) {
  162.             final List<BoundedPropagator> propagators = new ArrayList<>();
  163.             for (final EphemerisSegment<C> segment : this.getSegments()) {
  164.                 propagators.add(segment.getPropagator(attitudeProvider));
  165.             }
  166.             return new AggregateBoundedPropagator(propagators);
  167.         }

  168.     }

  169.     /**
  170.      * A segment of an ephemeris for a satellite.
  171.      *
  172.      * <p> Segments are typically used to split an ephemeris around discontinuous events
  173.      * such as maneuvers.
  174.      *
  175.      * @param <C> type of the Cartesian coordinates
  176.      * @author Evan Ward
  177.      * @see EphemerisFile
  178.      * @see SatelliteEphemeris
  179.      */
  180.     interface EphemerisSegment<C extends TimeStampedPVCoordinates> {

  181.         /**
  182.          * Get the standard gravitational parameter for the satellite.
  183.          *
  184.          * @return the gravitational parameter used in {@link #getPropagator(AttitudeProvider)}, in m³/s².
  185.          */
  186.         double getMu();

  187.         /**
  188.          * Get the reference frame for this ephemeris segment. The defining frame for
  189.          * {@link #getCoordinates()}.
  190.          *
  191.          * @return the reference frame for this segment. Never {@code null}.
  192.          */
  193.         Frame getFrame();

  194.         /**
  195.          * Get the inertial reference frame for this ephemeris segment. Defines the
  196.          * propagation frame for {@link #getPropagator(AttitudeProvider)}.
  197.          *
  198.          * <p>The default implementation returns {@link #getFrame()} if it is inertial.
  199.          * Otherwise it returns {@link Frame#getRoot()}. Implementors are encouraged to
  200.          * override this default implementation if a more suitable inertial frame is
  201.          * available.
  202.          *
  203.          * @return an reference frame that is inertial, i.e. {@link
  204.          * Frame#isPseudoInertial()} is {@code true}. May be the same as {@link
  205.          * #getFrame()} if it is inertial.
  206.          */
  207.         default Frame getInertialFrame() {
  208.             final Frame frame = getFrame();
  209.             if (frame.isPseudoInertial()) {
  210.                 return frame;
  211.             }
  212.             return Frame.getRoot();
  213.         }

  214.         /**
  215.          * Get the number of samples to use in interpolation.
  216.          *
  217.          * @return the number of points to use for interpolation.
  218.          */
  219.         int getInterpolationSamples();

  220.         /**
  221.          * Get which derivatives of position are available in this ephemeris segment.
  222.          *
  223.          * <p> While {@link #getCoordinates()} always returns position, velocity, and
  224.          * acceleration the return value from this method indicates which of those are in
  225.          * the ephemeris file and are actually valid.
  226.          *
  227.          * @return a value indicating if the file contains velocity and/or acceleration
  228.          * data.
  229.          */
  230.         CartesianDerivativesFilter getAvailableDerivatives();

  231.         /**
  232.          * Get the coordinates for this ephemeris segment in {@link #getFrame()}.
  233.          *
  234.          * @return a list of state vectors in chronological order. The coordinates are not
  235.          * necessarily evenly spaced in time. The value of {@link
  236.          * #getAvailableDerivatives()} indicates if the velocity or accelerations were
  237.          * specified in the file. Any position, velocity, or acceleration coordinates that
  238.          * are not specified in the ephemeris file are zero in the returned values.
  239.          */
  240.         List<C> getCoordinates();

  241.         /**
  242.          * Get the start date of this ephemeris segment.
  243.          *
  244.          * <p> The date returned by this method is equivalent to {@code
  245.          * getPropagator().getMinDate()}.
  246.          *
  247.          * @return ephemeris segment start date.
  248.          */
  249.         AbsoluteDate getStart();

  250.         /**
  251.          * Get the end date of this ephemeris segment.
  252.          *
  253.          * <p> The date returned by this method is equivalent to {@code
  254.          * getPropagator().getMaxDate()}.
  255.          *
  256.          * @return ephemeris segment end date.
  257.          */
  258.         AbsoluteDate getStop();

  259.         /**
  260.          * View this ephemeris segment as a propagator.
  261.          *
  262.          * <p>
  263.          * In order to view the ephemeris for this satellite as a {@link Propagator}
  264.          * several conditions must be met. An Orekit {@link Frame} must be constructable
  265.          * from the frame specification in the ephemeris file. This condition is met when
  266.          * {@link EphemerisSegment#getFrame()} return normally. Additionally,
  267.          * {@link #getMu()} must return a valid value. If these conditions are not met an
  268.          * {@link OrekitException} may be thrown by this method or by one of the methods
  269.          * of the returned {@link Propagator}.
  270.          * </p>
  271.          * <p>
  272.          * The {@link AttitudeProvider attitude provider} used is a {@link FrameAlignedProvider}
  273.          * aligned with the {@link #getInertialFrame() inertial frame}
  274.          * </p>
  275.          *
  276.          * <p>Each call to this method creates a new propagator.</p>
  277.          *
  278.          * @return a propagator for this ephemeris segment.
  279.          */
  280.         default BoundedPropagator getPropagator() {
  281.             return new EphemerisSegmentPropagator<>(this,
  282.                                                     new FrameAlignedProvider(getInertialFrame()));
  283.         }

  284.         /**
  285.          * View this ephemeris segment as a propagator.
  286.          *
  287.          * <p>
  288.          * In order to view the ephemeris for this satellite as a {@link Propagator}
  289.          * several conditions must be met. An Orekit {@link Frame} must be constructable
  290.          * from the frame specification in the ephemeris file. This condition is met when
  291.          * {@link EphemerisSegment#getFrame()} return normally. Additionally,
  292.          * {@link #getMu()} must return a valid value. If these conditions are not met an
  293.          * {@link OrekitException} may be thrown by this method or by one of the methods
  294.          * of the returned {@link Propagator}.
  295.          * </p>
  296.          *
  297.          * <p>Each call to this method creates a new propagator.</p>
  298.          *
  299.          * @param attitudeProvider provider for attitude computation
  300.          * @return a propagator for this ephemeris segment.
  301.          * @since 12.0
  302.          */
  303.         default BoundedPropagator getPropagator(final  AttitudeProvider attitudeProvider) {
  304.             return new EphemerisSegmentPropagator<>(this, attitudeProvider);
  305.         }

  306.     }

  307. }