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
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Map;
22
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 /**
33 * An interface for accessing the data stored in an ephemeris file and using the data to
34 * create a working {@link org.orekit.propagation.Propagator Propagator}.
35 *
36 * <p> An {@link EphemerisFile} consists of one or more satellites each with a unique ID
37 * within the file. The ephemeris for each satellite consists of one or more segments.
38 *
39 * <p> Some ephemeris file formats may supply additional information that is not available
40 * via this interface. In those cases it is recommended that the parser return a subclass
41 * of this interface to provide access to the additional information.
42 *
43 * @param <C> type of the Cartesian coordinates
44 * @param <S> type of the segment
45 * @author Evan Ward
46 * @see SatelliteEphemeris
47 * @see EphemerisSegment
48 */
49 public interface EphemerisFile<C extends TimeStampedPVCoordinates,
50 S extends EphemerisFile.EphemerisSegment<C>> {
51
52 /**
53 * Get the loaded ephemeris for each satellite in the file.
54 *
55 * @return a map from the satellite's ID to the information about that satellite
56 * contained in the file.
57 */
58 Map<String, ? extends SatelliteEphemeris<C, S>> getSatellites();
59
60 /**
61 * Contains the information about a single satellite from an {@link EphemerisFile}.
62 *
63 * <p> A satellite ephemeris consists of one or more {@link EphemerisSegment}s.
64 * Segments are typically used to split up an ephemeris at discontinuous events, such
65 * as a maneuver.
66 * @param <C> type of the Cartesian coordinates
67 * @param <S> type of the segment
68 * @author Evan Ward
69 * @see EphemerisFile
70 * @see EphemerisSegment
71 */
72 interface SatelliteEphemeris<C extends TimeStampedPVCoordinates,
73 S extends EphemerisSegment<C>> {
74
75 /**
76 * Get the satellite ID. The satellite ID is unique only within the same ephemeris
77 * file.
78 *
79 * @return the satellite's ID, never {@code null}.
80 */
81 String getId();
82
83 /**
84 * Get the standard gravitational parameter for the satellite.
85 *
86 * @return the gravitational parameter used in {@link #getPropagator()}, in m³/s².
87 */
88 double getMu();
89
90 /**
91 * Get the segments of the ephemeris.
92 *
93 * <p> Ephemeris segments are typically used to split an ephemeris around
94 * discontinuous events, such as maneuvers.
95 *
96 * @return the segments contained in the ephemeris file for this satellite.
97 */
98 List<S> getSegments();
99
100 /**
101 * Get the start date of the ephemeris.
102 *
103 * <p> The date returned by this method is equivalent to {@code
104 * getPropagator().getMinDate()}.
105 *
106 * @return ephemeris start date.
107 */
108 AbsoluteDate getStart();
109
110 /**
111 * Get the end date of the ephemeris.
112 *
113 * <p> The date returned by this method is equivalent to {@code getPropagator().getMaxDate()}.
114 *
115 * @return ephemeris end date.
116 */
117 AbsoluteDate getStop();
118
119 /**
120 * View this ephemeris as a propagator, combining data from all {@link
121 * #getSegments() segments}.
122 *
123 * <p>In order to view the ephemeris for this satellite as a {@link Propagator}
124 * several conditions must be met. An Orekit {@link Frame} must be constructable
125 * from the frame specification in the ephemeris file. This condition is met when
126 * {@link EphemerisSegment#getFrame()} return normally for all {@link
127 * #getSegments() segments}. If there are multiple segments they must be adjacent
128 * such that there are no duplicates or gaps in the ephemeris. The definition of
129 * adjacent depends on the ephemeris format as some formats define usable start
130 * and stop times that are different from the ephemeris data start and stop times.
131 * If these conditions are not met an {@link OrekitException} may be thrown by
132 * this method or by one of the methods of the returned {@link Propagator}.
133 *
134 * <p> Each call to this method creates a new propagator.
135 *
136 * @return a propagator for all the data in this ephemeris file.
137 */
138 default BoundedPropagator getPropagator() {
139 final List<BoundedPropagator> propagators = new ArrayList<>();
140 for (final EphemerisSegment<C> segment : this.getSegments()) {
141 propagators.add(segment.getPropagator());
142 }
143 return new AggregateBoundedPropagator(propagators);
144 }
145
146 }
147
148 /**
149 * A segment of an ephemeris for a satellite.
150 *
151 * <p> Segments are typically used to split an ephemeris around discontinuous events
152 * such as maneuvers.
153 *
154 * @param <C> type of the Cartesian coordinates
155 * @author Evan Ward
156 * @see EphemerisFile
157 * @see SatelliteEphemeris
158 */
159 interface EphemerisSegment<C extends TimeStampedPVCoordinates> {
160
161 /**
162 * Get the standard gravitational parameter for the satellite.
163 *
164 * @return the gravitational parameter used in {@link #getPropagator()}, in m³/s².
165 */
166 double getMu();
167
168 /**
169 * Get the reference frame for this ephemeris segment. The defining frame for
170 * {@link #getCoordinates()}.
171 *
172 * @return the reference frame for this segment. Never {@code null}.
173 */
174 Frame getFrame();
175
176 /**
177 * Get the inertial reference frame for this ephemeris segment. Defines the
178 * propagation frame for {@link #getPropagator()}.
179 *
180 * <p>The default implementation returns {@link #getFrame()} if it is inertial.
181 * Otherwise it returns {@link Frame#getRoot()}. Implementors are encouraged to
182 * override this default implementation if a more suitable inertial frame is
183 * available.
184 *
185 * @return an reference frame that is inertial, i.e. {@link
186 * Frame#isPseudoInertial()} is {@code true}. May be the same as {@link
187 * #getFrame()} if it is inertial.
188 */
189 default Frame getInertialFrame() {
190 final Frame frame = getFrame();
191 if (frame.isPseudoInertial()) {
192 return frame;
193 }
194 return Frame.getRoot();
195 }
196
197 /**
198 * Get the number of samples to use in interpolation.
199 *
200 * @return the number of points to use for interpolation.
201 */
202 int getInterpolationSamples();
203
204 /**
205 * Get which derivatives of position are available in this ephemeris segment.
206 *
207 * <p> While {@link #getCoordinates()} always returns position, velocity, and
208 * acceleration the return value from this method indicates which of those are in
209 * the ephemeris file and are actually valid.
210 *
211 * @return a value indicating if the file contains velocity and/or acceleration
212 * data.
213 */
214 CartesianDerivativesFilter getAvailableDerivatives();
215
216 /**
217 * Get the coordinates for this ephemeris segment in {@link #getFrame()}.
218 *
219 * @return a list of state vectors in chronological order. The coordinates are not
220 * necessarily evenly spaced in time. The value of {@link
221 * #getAvailableDerivatives()} indicates if the velocity or accelerations were
222 * specified in the file. Any position, velocity, or acceleration coordinates that
223 * are not specified in the ephemeris file are zero in the returned values.
224 */
225 List<C> getCoordinates();
226
227 /**
228 * Get the start date of this ephemeris segment.
229 *
230 * <p> The date returned by this method is equivalent to {@code
231 * getPropagator().getMinDate()}.
232 *
233 * @return ephemeris segment start date.
234 */
235 AbsoluteDate getStart();
236
237 /**
238 * Get the end date of this ephemeris segment.
239 *
240 * <p> The date returned by this method is equivalent to {@code
241 * getPropagator().getMaxDate()}.
242 *
243 * @return ephemeris segment end date.
244 */
245 AbsoluteDate getStop();
246
247 /**
248 * View this ephemeris segment as a propagator.
249 *
250 * <p>In order to view the ephemeris for this satellite as a {@link Propagator}
251 * several conditions must be met. An Orekit {@link Frame} must be constructable
252 * from the frame specification in the ephemeris file. This condition is met when
253 * {@link EphemerisSegment#getFrame()} return normally. Additionally,
254 * {@link #getMu()} must return a valid value. If these conditions are not met an
255 * {@link OrekitException} may be thrown by this method or by one of the methods
256 * of the returned {@link Propagator}.
257 *
258 * <p> Each call to this method creates a new propagator.
259 *
260 * @return a propagator for this ephemeris segment.
261 */
262 default BoundedPropagator getPropagator() {
263 return new EphemerisSegmentPropagator<>(this);
264 }
265
266 }
267
268 }