1   /* Copyright 2022-2025 Bryan Cazabonne
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    * Bryan Cazabonne 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.conversion;
18  
19  import org.orekit.attitudes.AttitudeProvider;
20  import org.orekit.attitudes.FrameAlignedProvider;
21  import org.orekit.estimation.leastsquares.AbstractBatchLSModel;
22  import org.orekit.estimation.leastsquares.BatchLSModel;
23  import org.orekit.estimation.leastsquares.ModelObserver;
24  import org.orekit.estimation.measurements.ObservedMeasurement;
25  import org.orekit.orbits.Orbit;
26  import org.orekit.orbits.PositionAngleType;
27  import org.orekit.propagation.SpacecraftState;
28  import org.orekit.propagation.SpacecraftStateInterpolator;
29  import org.orekit.propagation.StateCovariance;
30  import org.orekit.propagation.analytical.Ephemeris;
31  import org.orekit.time.TimeInterpolator;
32  import org.orekit.time.TimeStampedPair;
33  import org.orekit.utils.ParameterDriversList;
34  
35  import java.util.ArrayList;
36  import java.util.List;
37  
38  /**
39   * Builder for Ephemeris propagator.
40   *
41   * @author Bryan Cazabonne
42   * @author Vincent Cucchietti
43   * @since 11.3
44   */
45  public class EphemerisPropagatorBuilder extends AbstractPropagatorBuilder<Ephemeris> {
46  
47      /** Default position scale (not used for ephemeris based estimation). */
48      private static final double DEFAULT_SCALE = 10.0;
49  
50      /** List of spacecraft states. */
51      private final List<SpacecraftState> states;
52  
53      /** List of covariances. **/
54      private final List<StateCovariance> covariances;
55  
56      /** Spacecraft state interpolator. */
57      private final TimeInterpolator<SpacecraftState> stateInterpolator;
58  
59      /** State covariance interpolator. */
60      private final TimeInterpolator<TimeStampedPair<Orbit, StateCovariance>> covarianceInterpolator;
61  
62      /** Attitude provider. */
63      private final AttitudeProvider provider;
64  
65      /**
66       * Constructor using the default attitude provider.
67       * <p>
68       * The default attitude provider is an {@link org.orekit.attitudes.FrameAlignedProvider inertial provider} built from the frame of the first
69       * spacecraft state instance in given list
70       *
71       * @param states list of spacecraft states
72       * @param stateInterpolator spacecraft state interpolator
73       */
74      public EphemerisPropagatorBuilder(final List<SpacecraftState> states,
75                                        final TimeInterpolator<SpacecraftState> stateInterpolator) {
76          this(states, stateInterpolator, states.isEmpty() ? null : new FrameAlignedProvider(states.get(0).getFrame()));
77      }
78  
79      /**
80       * Constructor.
81       *
82       * @param states list of spacecraft states
83       * @param stateInterpolator spacecraft state interpolator
84       * @param attitudeProvider attitude law to use
85       */
86      public EphemerisPropagatorBuilder(final List<SpacecraftState> states,
87                                        final TimeInterpolator<SpacecraftState> stateInterpolator,
88                                        final AttitudeProvider attitudeProvider) {
89          this(states, stateInterpolator, new ArrayList<>(), null, attitudeProvider);
90      }
91  
92      /**
93       * Constructor.
94       *
95       * @param states list of spacecraft states
96       * @param interpolationPoints number of interpolation points
97       * @param extrapolationThreshold extrapolation threshold beyond which the propagation will fail
98       * @param attitudeProvider attitude law to use
99       */
100     public EphemerisPropagatorBuilder(final List<SpacecraftState> states,
101                                       final int interpolationPoints,
102                                       final double extrapolationThreshold,
103                                       final AttitudeProvider attitudeProvider) {
104         this(states,
105              new SpacecraftStateInterpolator(interpolationPoints, extrapolationThreshold,
106                                              states.get(0).getFrame(), states.get(0).getFrame()),
107              attitudeProvider);
108     }
109 
110     /**
111      * Constructor with covariances and default attitude provider.
112      * <p>
113      * The default attitude provider is an {@link FrameAlignedProvider inertial provider} built from the frame of the first
114      * spacecraft state instance in given list
115      *
116      * @param states list of spacecraft states
117      * @param stateInterpolator spacecraft state interpolator
118      * @param covariances tabulated covariances associated to tabulated states
119      * @param covarianceInterpolator covariance interpolator
120      *
121      * @see StateCovariance
122      * @see FrameAlignedProvider
123      */
124     public EphemerisPropagatorBuilder(final List<SpacecraftState> states,
125                                       final TimeInterpolator<SpacecraftState> stateInterpolator,
126                                       final List<StateCovariance> covariances,
127                                       final TimeInterpolator<TimeStampedPair<Orbit, StateCovariance>> covarianceInterpolator) {
128         this(states, stateInterpolator, covariances, covarianceInterpolator,
129              states.isEmpty() ? null : new FrameAlignedProvider(states.get(0).getFrame()));
130     }
131 
132     /**
133      * Constructor.
134      *
135      * @param states list of spacecraft states
136      * @param stateInterpolator spacecraft state interpolator
137      * @param covariances tabulated covariances associated to tabulated states
138      * @param covarianceInterpolator covariance interpolator
139      * @param attitudeProvider attitude law to use
140      */
141     public EphemerisPropagatorBuilder(final List<SpacecraftState> states,
142                                       final TimeInterpolator<SpacecraftState> stateInterpolator,
143                                       final List<StateCovariance> covariances,
144                                       final TimeInterpolator<TimeStampedPair<Orbit, StateCovariance>> covarianceInterpolator,
145                                       final AttitudeProvider attitudeProvider) {
146         super(states.get(0).getOrbit(), PositionAngleType.TRUE, DEFAULT_SCALE, false, attitudeProvider);
147         deselectDynamicParameters();
148 
149         // Check input consistency the same way Ephemeris is checking consistency
150         Ephemeris.checkInputConsistency(states, stateInterpolator, covariances, covarianceInterpolator);
151 
152         this.states                 = states;
153         this.stateInterpolator      = stateInterpolator;
154         this.covariances            = covariances == null ? new ArrayList<>() : covariances;
155         this.covarianceInterpolator = covarianceInterpolator;
156         this.provider               = attitudeProvider;
157     }
158 
159     /** {@inheritDoc}. */
160     @Override
161     public Ephemeris buildPropagator(final double[] normalizedParameters) {
162         if (!covariances.isEmpty() && covarianceInterpolator != null) {
163             return new Ephemeris(states, stateInterpolator, covariances, covarianceInterpolator, provider);
164         }
165         return new Ephemeris(states, stateInterpolator, provider);
166 
167     }
168 
169     /** {@inheritDoc} */
170     @Override
171     public AbstractBatchLSModel buildLeastSquaresModel(final PropagatorBuilder[] builders,
172                                                        final List<ObservedMeasurement<?>> measurements,
173                                                        final ParameterDriversList estimatedMeasurementsParameters,
174                                                        final ModelObserver observer) {
175         return new BatchLSModel(builders, measurements, estimatedMeasurementsParameters, observer);
176     }
177 
178 }