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é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 }