/* Contributed in the public domain. * 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.files.general; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.orekit.errors.OrekitException; import org.orekit.frames.Frame; import org.orekit.propagation.BoundedPropagator; import org.orekit.propagation.Propagator; import org.orekit.propagation.analytical.AggregateBoundedPropagator; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScale; import org.orekit.utils.CartesianDerivativesFilter; import org.orekit.utils.TimeStampedPVCoordinates; /** * An interface for accessing the data stored in an ephemeris file and using the data to * create a working {@link org.orekit.propagation.Propagator Propagator}. * * <p> An {@link EphemerisFile} consists of one or more satellites each an ID unique * within the file. The ephemeris for each satellite consists of one or more segments. * * <p> Some ephemeris file formats may supply additional information that is not available * via this interface. In those cases it is recommended that the parser return a subclass * of this interface to provide access to the additional information. * * @author Evan Ward * @see SatelliteEphemeris * @see EphemerisSegment */ public interface EphemerisFile { /** * Get the loaded ephemeris for each satellite in the file. * * @return a map from the satellite's ID to the information about that satellite * contained in the file. */ Map<String, ? extends SatelliteEphemeris> getSatellites(); /** * Contains the information about a single satellite from an {@link EphemerisFile}. * * <p> A satellite ephemeris consists of one or more {@link EphemerisSegment}s. * Segments are typically used to split up an ephemeris at discontinuous events, such * as a maneuver. * * @author Evan Ward * @see EphemerisFile * @see EphemerisSegment */ interface SatelliteEphemeris { /** * Get the satellite ID. The satellite ID is unique only within the same ephemeris * file. * * @return the satellite's ID, never {@code null}. */ String getId(); /** * Get the standard gravitational parameter for the satellite. * * @return the gravitational parameter use in {@link #getPropagator()}, in m^3 / * s^2. */ double getMu(); /** * Get the segments of the ephemeris. * * <p> Ephemeris segments are typically used to split an ephemeris around * discontinuous events, such as maneuvers. * * @return the segments contained in the ephemeris file for this satellite. */ List<? extends EphemerisSegment> getSegments(); /** * Get the start date of the ephemeris. * * <p> The date returned by this method is equivalent to {@code * getPropagator().getMinDate()}. * * @return ephemeris start date. */ AbsoluteDate getStart(); /** * Get the end date of the ephemeris. * * <p> The date returned by this method is equivalent to {@code * getPropagator().getMaxDate()}. * * @return ephemeris end date. */ AbsoluteDate getStop(); /** * View this ephemeris as a propagator, combining data from all {@link * #getSegments() segments}. * * <p>In order to view the ephemeris for this satellite as a {@link Propagator} * several conditions must be met. An Orekit {@link Frame} and {@link TimeScale} * must be constructable from the frame and time scale specification in the * ephemeris file. This condition is met when {@link EphemerisSegment#getFrame()} * and {@link EphemerisSegment#getTimeScale()} return normally for all {@link * #getSegments() segments}. If there are multiple segments they must be adjacent * such that there are no duplicates or gaps in the ephemeris. The definition of * adjacent depends on the ephemeris format as some formats define usable start * and stop times that are different from the ephemeris data start and stop times. * If these conditions are not met an {@link OrekitException} may be thrown by * this method or by one of the methods of the returned {@link Propagator}. * * <p> Each call to this method creates a new propagator. * * @return a propagator for all the data in this ephemeris file. * @throws OrekitException if any of the conditions are not met. */ default BoundedPropagator getPropagator() throws OrekitException { final List<BoundedPropagator> propagators = new ArrayList<>(); for (final EphemerisSegment segment : this.getSegments()) { propagators.add(segment.getPropagator()); } return new AggregateBoundedPropagator(propagators); } } /** * A segment of an ephemeris for a satellite. * * <p> Segments are typically used to split an ephemeris around discontinuous events * such as maneuvers. * * @author Evan Ward * @see EphemerisFile * @see SatelliteEphemeris */ interface EphemerisSegment { /** * Get the standard gravitational parameter for the satellite. * * @return the gravitational parameter use in {@link #getPropagator()}, in m^3 / * s^2. */ double getMu(); /** * Get the name of the center of the coordinate system the ephemeris is provided * in. This may be a natural origin, such as the center of the Earth, another * satellite, etc. * * @return the name of the frame center */ String getFrameCenterString(); /** * Get the defining frame for this ephemeris segment. * * @return the frame identifier, as specified in the ephemeris file, or {@code * null} if the ephemeris file does not specify a frame. */ String getFrameString(); /** * Get the reference frame for this ephemeris segment. * * @return the reference frame for this segment. Never {@code null}. * @throws OrekitException if a frame cannot be created from {@link * #getFrameString()} and there is no default frame. */ Frame getFrame() throws OrekitException; /** * Get the time scale for this ephemeris segment. * * @return the time scale identifier, as specified in the ephemeris file, or * {@code null} if the ephemeris file does not specify a time scale. */ String getTimeScaleString(); /** * Get the time scale for this ephemeris segment. * * @return the time scale for this segment. Never {@code null}. * @throws OrekitException if a time scale can not be constructed based on {@link * #getTimeScaleString()} and there is no default time * scale. */ TimeScale getTimeScale() throws OrekitException; /** * Get the number of samples to use in interpolation. * * @return the number of points to use for interpolation. */ int getInterpolationSamples(); /** * Get which derivatives of position are available in this ephemeris segment. * * <p> While {@link #getCoordinates()} always returns position, velocity, and * acceleration the return value from this method indicates which of those are in * the ephemeris file and are actually valid. * * @return a value indicating if the file contains velocity and/or acceleration * data. */ CartesianDerivativesFilter getAvailableDerivatives(); /** * Get the coordinates for this ephemeris segment. * * @return a list of state vectors in chronological order. The coordinates are not * necessarily evenly spaced in time. The value of {@link * #getAvailableDerivatives()} indicates if the velocity or accelerations were * specified in the file. Any position, velocity, or acceleration coordinates that * are not specified in the ephemeris file are zero in the returned values. */ List<? extends TimeStampedPVCoordinates> getCoordinates(); /** * Get the start date of this ephemeris segment. * * <p> The date returned by this method is equivalent to {@code * getPropagator().getMinDate()}. * * @return ephemeris segment start date. */ AbsoluteDate getStart(); /** * Get the end date of this ephemeris segment. * * <p> The date returned by this method is equivalent to {@code * getPropagator().getMaxDate()}. * * @return ephemeris segment end date. */ AbsoluteDate getStop(); /** * View this ephemeris segment as a propagator. * * <p>In order to view the ephemeris for this satellite as a {@link Propagator} * several conditions must be met. An Orekit {@link Frame} and {@link TimeScale} * must be constructable from the frame and time scale specification in the * ephemeris file. This condition is met when {@link EphemerisSegment#getFrame()} * and {@link EphemerisSegment#getTimeScale()} return normally. Additionally, * {@link #getMu()} must return a valid value. If these conditions are not met an * {@link OrekitException} may be thrown by this method or by one of the methods * of the returned {@link Propagator}. * * <p> Each call to this method creates a new propagator. * * @return a propagator for this ephemeris segment. * @throws OrekitException if any of the conditions are not met. */ default BoundedPropagator getPropagator() throws OrekitException { return new EphemerisSegmentPropagator(this); } } }