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;
18  
19  import java.util.Collection;
20  import java.util.List;
21  
22  import org.hipparchus.geometry.euclidean.threed.Rotation;
23  import org.orekit.annotation.DefaultDataContext;
24  import org.orekit.attitudes.AttitudeProvider;
25  import org.orekit.attitudes.InertialProvider;
26  import org.orekit.data.DataContext;
27  import org.orekit.frames.Frame;
28  import org.orekit.frames.Frames;
29  import org.orekit.propagation.events.EventDetector;
30  import org.orekit.propagation.sampling.OrekitFixedStepHandler;
31  import org.orekit.propagation.sampling.OrekitStepHandler;
32  import org.orekit.time.AbsoluteDate;
33  import org.orekit.utils.PVCoordinatesProvider;
34  
35  /** This interface provides a way to propagate an orbit at any time.
36   *
37   * <p>This interface is the top-level abstraction for orbit propagation.
38   * It only allows propagation to a predefined date.
39   * It is implemented by analytical models which have no time limit,
40   * by orbit readers based on external data files, by numerical integrators
41   * using rich force models and by continuous models built after numerical
42   * integration has been completed and dense output data as been
43   * gathered.</p>
44   * <p>Note that one single propagator cannot be called from multiple threads.
45   * Its configuration can be changed as there is at least a {@link
46   * #resetInitialState(SpacecraftState)} method, and even propagators that do
47   * not support resetting state (like the {@link
48   * org.orekit.propagation.analytical.tle.TLEPropagator TLEPropagator} do
49   * cache some internal data during computation. However, as long as they
50   * are configured with independent building blocks (mainly event handlers
51   * and step handlers that may preserve some internal state), and as long
52   * as they are called from one thread only, they <em>can</em> be used in
53   * multi-threaded applications. Synchronizing several propagators to run in
54   * parallel is also possible using {@link PropagatorsParallelizer}.</p>
55   * @author Luc Maisonobe
56   * @author V&eacute;ronique Pommier-Maurussane
57   *
58   */
59  
60  public interface Propagator extends PVCoordinatesProvider {
61  
62      /** Default mass. */
63      double DEFAULT_MASS = 1000.0;
64  
65      /** Default attitude provider.
66       *
67       * <p>This field uses the {@link DataContext#getDefault() default data context}.
68       *
69       * @see InertialProvider#InertialProvider(Rotation, Frame)
70       * @see #getDefaultLaw(Frames)
71       */
72      @DefaultDataContext
73      AttitudeProvider DEFAULT_LAW = InertialProvider.EME2000_ALIGNED;
74  
75      /** Indicator for slave mode. */
76      int SLAVE_MODE = 0;
77  
78      /** Indicator for master mode. */
79      int MASTER_MODE = 1;
80  
81      /** Indicator for ephemeris generation mode. */
82      int EPHEMERIS_GENERATION_MODE = 2;
83  
84      /**
85       * Get a default law using the given frames. A data context aware replacement for
86       * {@link #DEFAULT_LAW}.
87       *
88       * @param frames the set of frames to use.
89       * @return attitude law.
90       */
91      static AttitudeProvider getDefaultLaw(final Frames frames) {
92          return new InertialProvider(Rotation.IDENTITY, frames.getEME2000());
93      }
94  
95      /** Get the current operating mode of the propagator.
96       * @return one of {@link #SLAVE_MODE}, {@link #MASTER_MODE},
97       * {@link #EPHEMERIS_GENERATION_MODE}
98       * @see #setSlaveMode()
99       * @see #setMasterMode(double, OrekitFixedStepHandler)
100      * @see #setMasterMode(OrekitStepHandler)
101      * @see #setEphemerisMode()
102      */
103     int getMode();
104 
105     /** Set the propagator to slave mode.
106      * <p>This mode is used when the user needs only the final orbit at the target time.
107      *  The (slave) propagator computes this result and return it to the calling
108      *  (master) application, without any intermediate feedback.
109      * <p>This is the default mode.</p>
110      * @see #setMasterMode(double, OrekitFixedStepHandler)
111      * @see #setMasterMode(OrekitStepHandler)
112      * @see #setEphemerisMode()
113      * @see #getMode()
114      * @see #SLAVE_MODE
115      */
116     void setSlaveMode();
117 
118     /** Set the propagator to master mode with fixed steps.
119      * <p>This mode is used when the user needs to have some custom function called at the
120      * end of each finalized step during integration. The (master) propagator integration
121      * loop calls the (slave) application callback methods at each finalized step.</p>
122      * @param h fixed stepsize (s)
123      * @param handler handler called at the end of each finalized step
124      * @see #setSlaveMode()
125      * @see #setMasterMode(OrekitStepHandler)
126      * @see #setEphemerisMode()
127      * @see #getMode()
128      * @see #MASTER_MODE
129      */
130     void setMasterMode(double h, OrekitFixedStepHandler handler);
131 
132     /** Set the propagator to master mode with variable steps.
133      * <p>This mode is used when the user needs to have some custom function called at the
134      * end of each finalized step during integration. The (master) propagator integration
135      * loop calls the (slave) application callback methods at each finalized step.</p>
136      * @param handler handler called at the end of each finalized step
137      * @see #setSlaveMode()
138      * @see #setMasterMode(double, OrekitFixedStepHandler)
139      * @see #setEphemerisMode()
140      * @see #getMode()
141      * @see #MASTER_MODE
142      */
143     void setMasterMode(OrekitStepHandler handler);
144 
145     /** Set the propagator to ephemeris generation mode.
146      *  <p>This mode is used when the user needs random access to the orbit state at any time
147      *  between the initial and target times, and in no sequential order. A typical example is
148      *  the implementation of search and iterative algorithms that may navigate forward and
149      *  backward inside the propagation range before finding their result.</p>
150      *  <p>Beware that since this mode stores <strong>all</strong> intermediate results,
151      *  it may be memory intensive for long integration ranges and high precision/short
152      *  time steps.</p>
153      * @see #getGeneratedEphemeris()
154      * @see #setSlaveMode()
155      * @see #setMasterMode(double, OrekitFixedStepHandler)
156      * @see #setMasterMode(OrekitStepHandler)
157      * @see #getMode()
158      * @see #EPHEMERIS_GENERATION_MODE
159      */
160     void setEphemerisMode();
161 
162     /**
163      * Set the propagator to ephemeris generation mode with the specified handler for each
164      * integration step.
165      *
166      * <p>This mode is used when the user needs random access to the orbit state at any
167      * time between the initial and target times, as well as access to the steps computed
168      * by the integrator as in Master Mode. A typical example is the implementation of
169      * search and iterative algorithms that may navigate forward and backward inside the
170      * propagation range before finding their result.</p>
171      *
172      * <p>Beware that since this mode stores <strong>all</strong> intermediate results, it
173      * may be memory intensive for long integration ranges and high precision/short time
174      * steps.</p>
175      *
176      * @param handler handler called at the end of each finalized step
177      * @see #setEphemerisMode()
178      * @see #getGeneratedEphemeris()
179      * @see #setSlaveMode()
180      * @see #setMasterMode(double, OrekitFixedStepHandler)
181      * @see #setMasterMode(OrekitStepHandler)
182      * @see #getMode()
183      * @see #EPHEMERIS_GENERATION_MODE
184      */
185     void setEphemerisMode(OrekitStepHandler handler);
186 
187     /** Get the ephemeris generated during propagation.
188      * @return generated ephemeris
189      * @exception IllegalStateException if the propagator was not set in ephemeris
190      * generation mode before propagation
191      * @see #setEphemerisMode()
192      */
193     BoundedPropagator getGeneratedEphemeris() throws IllegalStateException;
194 
195     /** Get the propagator initial state.
196      * @return initial state
197      */
198     SpacecraftState getInitialState();
199 
200     /** Reset the propagator initial state.
201      * @param state new initial state to consider
202      */
203     void resetInitialState(SpacecraftState state);
204 
205     /** Add a set of user-specified state parameters to be computed along with the orbit propagation.
206      * @param additionalStateProvider provider for additional state
207      */
208     void addAdditionalStateProvider(AdditionalStateProvider additionalStateProvider);
209 
210     /** Get an unmodifiable list of providers for additional state.
211      * @return providers for the additional states
212      */
213     List<AdditionalStateProvider> getAdditionalStateProviders();
214 
215     /** Check if an additional state is managed.
216      * <p>
217      * Managed states are states for which the propagators know how to compute
218      * its evolution. They correspond to additional states for which an
219      * {@link AdditionalStateProvider additional state provider} has been registered
220      * by calling the {@link #addAdditionalStateProvider(AdditionalStateProvider)
221      * addAdditionalStateProvider} method. If the propagator is an {@link
222      * org.orekit.propagation.integration.AbstractIntegratedPropagator integrator-based
223      * propagator}, the states for which a set of {@link
224      * org.orekit.propagation.integration.AdditionalEquations additional equations} has
225      * been registered by calling the {@link
226      * org.orekit.propagation.integration.AbstractIntegratedPropagator#addAdditionalEquations(
227      * org.orekit.propagation.integration.AdditionalEquations) addAdditionalEquations}
228      * method are also counted as managed additional states.
229      * </p>
230      * <p>
231      * Additional states that are present in the {@link #getInitialState() initial state}
232      * but have no evolution method registered are <em>not</em> considered as managed states.
233      * These unmanaged additional states are not lost during propagation, though. Their
234      * value are piecewise constant between state resets that may change them if some
235      * event handler {@link
236      * org.orekit.propagation.events.handlers.EventHandler#resetState(EventDetector,
237      * SpacecraftState) resetState} method is called at an event occurrence and happens
238      * to change the unmanaged additional state.
239      * </p>
240      * @param name name of the additional state
241      * @return true if the additional state is managed
242      */
243     boolean isAdditionalStateManaged(String name);
244 
245     /** Get all the names of all managed states.
246      * @return names of all managed states
247      */
248     String[] getManagedAdditionalStates();
249 
250     /** Add an event detector.
251      * @param detector event detector to add
252      * @see #clearEventsDetectors()
253      * @see #getEventsDetectors()
254      * @param <T> class type for the generic version
255      */
256     <T extends EventDetector> void addEventDetector(T detector);
257 
258     /** Get all the events detectors that have been added.
259      * @return an unmodifiable collection of the added detectors
260      * @see #addEventDetector(EventDetector)
261      * @see #clearEventsDetectors()
262      */
263     Collection<EventDetector> getEventsDetectors();
264 
265     /** Remove all events detectors.
266      * @see #addEventDetector(EventDetector)
267      * @see #getEventsDetectors()
268      */
269     void clearEventsDetectors();
270 
271     /** Get attitude provider.
272      * @return attitude provider
273      */
274     AttitudeProvider getAttitudeProvider();
275 
276     /** Set attitude provider.
277      * @param attitudeProvider attitude provider
278      */
279     void setAttitudeProvider(AttitudeProvider attitudeProvider);
280 
281     /** Get the frame in which the orbit is propagated.
282      * <p>
283      * The propagation frame is the definition frame of the initial
284      * state, so this method should be called after this state has
285      * been set, otherwise it may return null.
286      * </p>
287      * @return frame in which the orbit is propagated
288      * @see #resetInitialState(SpacecraftState)
289      */
290     Frame getFrame();
291 
292     /** Propagate towards a target date.
293      * <p>Simple propagators use only the target date as the specification for
294      * computing the propagated state. More feature rich propagators can consider
295      * other information and provide different operating modes or G-stop
296      * facilities to stop at pinpointed events occurrences. In these cases, the
297      * target date is only a hint, not a mandatory objective.</p>
298      * @param target target date towards which orbit state should be propagated
299      * @return propagated state
300      */
301     SpacecraftState propagate(AbsoluteDate target);
302 
303     /** Propagate from a start date towards a target date.
304      * <p>Those propagators use a start date and a target date to
305      * compute the propagated state. For propagators using event detection mechanism,
306      * if the provided start date is different from the initial state date, a first,
307      * simple propagation is performed, without processing any event computation.
308      * Then complete propagation is performed from start date to target date.</p>
309      * @param start start date from which orbit state should be propagated
310      * @param target target date to which orbit state should be propagated
311      * @return propagated state
312      */
313     SpacecraftState propagate(AbsoluteDate../../org/orekit/time/AbsoluteDate.html#AbsoluteDate">AbsoluteDate start, AbsoluteDate target);
314 
315 }