1   /* Copyright 2002-2025 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.integration;
18  
19  import org.orekit.attitudes.AttitudeProvider;
20  import org.orekit.frames.Frame;
21  import org.orekit.orbits.OrbitType;
22  import org.orekit.orbits.PositionAngleType;
23  import org.orekit.propagation.PropagationType;
24  import org.orekit.propagation.SpacecraftState;
25  import org.orekit.time.AbsoluteDate;
26  
27  /** This class maps between raw double elements and {@link SpacecraftState} instances.
28   * @author Luc Maisonobe
29   * @since 6.0
30   */
31  public abstract class StateMapper {
32  
33      /** Reference date. */
34      private final AbsoluteDate referenceDate;
35  
36      /** Propagation orbit type. */
37      private final OrbitType orbitType;
38  
39      /** Position angle type. */
40      private final PositionAngleType angleType;
41  
42      /** Central attraction coefficient. */
43      private final double mu;
44  
45      /** Inertial frame. */
46      private final Frame frame;
47  
48      /** Attitude provider. */
49      private AttitudeProvider attitudeProvider;
50  
51      /** Simple constructor.
52       * <p>
53       * The position parameter type is meaningful only if {@link
54       * #getOrbitType() propagation orbit type}
55       * support it. As an example, it is not meaningful for propagation
56       * in {@link OrbitType#CARTESIAN Cartesian} parameters.
57       * </p>
58       * @param referenceDate reference date
59       * @param mu central attraction coefficient (m³/s²)
60       * @param orbitType orbit type to use for mapping, null for
61       * propagating using {@link org.orekit.utils.AbsolutePVCoordinates AbsolutePVCoordinates}
62       * rather than {@link org.orekit.orbits Orbit}
63       * @param positionAngleType angle type to use for propagation
64       * @param attitudeProvider attitude provider
65       * @param frame inertial frame
66       */
67      protected StateMapper(final AbsoluteDate referenceDate, final double mu,
68                            final OrbitType orbitType, final PositionAngleType positionAngleType,
69                            final AttitudeProvider attitudeProvider, final Frame frame) {
70          this.referenceDate    = referenceDate;
71          this.mu               = mu;
72          this.orbitType        = orbitType;
73          this.angleType        = positionAngleType;
74          this.attitudeProvider = attitudeProvider;
75          this.frame            = frame;
76      }
77  
78      /** Get reference date.
79       * @return reference date
80       */
81      public AbsoluteDate getReferenceDate() {
82          return referenceDate;
83      }
84  
85      /** Get propagation parameter type.
86       * @return orbit type used for propagation
87       */
88      public OrbitType getOrbitType() {
89          return orbitType;
90      }
91  
92      /** Get propagation parameter type.
93       * @return angle type to use for propagation
94       */
95      public PositionAngleType getPositionAngleType() {
96          return angleType;
97      }
98  
99      /** Get the central attraction coefficient μ.
100      * @return mu central attraction coefficient (m³/s²)
101      */
102     public double getMu() {
103         return mu;
104     }
105 
106     /** Get the inertial frame.
107      * @return inertial frame
108      */
109     public Frame getFrame() {
110         return frame;
111     }
112 
113     /** Get the attitude provider.
114      * @return attitude provider
115      */
116     public AttitudeProvider getAttitudeProvider() {
117         return attitudeProvider;
118     }
119 
120     /** Set the attitude provider.
121      * @param attitudeProvider the provider to set
122      */
123     public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
124         this.attitudeProvider = attitudeProvider;
125     }
126 
127     /** Map the raw double time offset to a date.
128      * @param t date offset
129      * @return date
130      */
131     public AbsoluteDate mapDoubleToDate(final double t) {
132         return referenceDate.shiftedBy(t);
133     }
134 
135     /**
136      * Map the raw double time offset to a date.
137      *
138      * @param t    date offset
139      * @param date The expected date.
140      * @return {@code date} if it is the same time as {@code t} to within the
141      * lower precision of the latter. Otherwise a new date is returned that
142      * corresponds to time {@code t}.
143      */
144     public AbsoluteDate mapDoubleToDate(final double t,
145                                         final AbsoluteDate date) {
146         if (date.durationFrom(referenceDate) == t) {
147             return date;
148         } else {
149             return mapDoubleToDate(t);
150         }
151     }
152 
153     /** Map a date to a raw double time offset.
154      * @param date date
155      * @return time offset
156      */
157     public double mapDateToDouble(final AbsoluteDate date) {
158         return date.durationFrom(referenceDate);
159     }
160 
161     /** Map the raw double components to a spacecraft state.
162      * @param t date offset
163      * @param y state components
164      * @param yDot time derivatives of the state components (null if unknown, in which case Keplerian motion is assumed)
165      * @param type type of the elements used to build the state (mean or osculating).
166      * @return spacecraft state
167      */
168     public SpacecraftState mapArrayToState(final double t, final double[] y, final double[] yDot, final PropagationType type) {
169         return mapArrayToState(mapDoubleToDate(t), y, yDot, type);
170     }
171 
172     /** Map the raw double components to a spacecraft state.
173      * @param date of the state components
174      * @param y state components
175      * @param yDot time derivatives of the state components (null if unknown, in which case Keplerian motion is assumed)
176      * @param type type of the elements used to build the state (mean or osculating).
177      * @return spacecraft state
178      */
179     public abstract SpacecraftState mapArrayToState(AbsoluteDate date, double[] y, double[] yDot, PropagationType type);
180 
181     /** Map a spacecraft state to raw double components.
182      * @param state state to map
183      * @param y placeholder where to put the components
184      * @param yDot placeholder where to put the components derivatives
185      */
186     public abstract void mapStateToArray(SpacecraftState state, double[] y, double[] yDot);
187 
188 }