1   /* Copyright 2002-2026 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  
18  package org.orekit.propagation.relative;
19  
20  import org.orekit.frames.Frame;
21  import org.orekit.frames.LOF;
22  import org.orekit.frames.Transform;
23  import org.orekit.orbits.Orbit;
24  import org.orekit.propagation.AdditionalDataProvider;
25  import org.orekit.propagation.SpacecraftState;
26  import org.orekit.utils.TimeStampedPVCoordinates;
27  
28  /**
29   * Interface for relative provider.
30   * <p>
31   * A relative provider is an interface extending AdditionalDataProvider to provide the relative state of a chaser S/C in
32   * regard to a target S/C as an AdditionalData. The target S/C is propagated with the "main" propagator where the
33   * additional data is added.
34   * </p>
35   *
36   * @author Romain Cuvillon
37   * @since 14.0
38   */
39  public interface RelativeProvider extends AdditionalDataProvider<double[]> {
40  
41      /**
42       * Returns the LOF used by the provider.
43       * @return the LOF used by the provider
44       */
45      LOF getLof();
46  
47      /**
48       * Get the initial TimeStampedPVCoordinates of the chaser in the Local Orbital Frame of the target.
49       *
50       * @return initial TimeStampedPVCoordinates of the chaser in target's LOF
51       */
52      TimeStampedPVCoordinates getInitialChaserPVTLof();
53  
54      /**
55       * Set the initial TimeStampedPVCoordinates of the chaser in the Local Orbital Frame of the target.
56       *
57       * @param initialChaserPVTLof initial TimeStampedPVCoordinates of the chaser in target's LOF
58       */
59      void setInitialChaserPVTLof(TimeStampedPVCoordinates initialChaserPVTLof);
60  
61      /**
62       * Extracts the chaser's PVT in the target LOF from the given target {@link SpacecraftState}.
63       *
64       * @param targetState target SpacecraftState
65       * @return chaser's TimeStampedPVCoordinates in target's LOF
66       */
67      TimeStampedPVCoordinates extractChaserPVT(SpacecraftState targetState);
68  
69      /**
70       * Extracts the chaser's PVT from the given target {@link SpacecraftState} and converts it to the desired output
71       * frame.
72       *
73       * @param targetState target SpacecraftState
74       * @param outputFrame desired frame in which to extract chaser's TimeStampedPVCoordinates
75       * @return TimeStampedPVCoordinates in desired frame
76       */
77      default TimeStampedPVCoordinates extractChaserPVT(final SpacecraftState targetState, final Frame outputFrame) {
78  
79          // Extract chaser PVT in target's LOF
80          final TimeStampedPVCoordinates chaserPVTLOF = extractChaserPVT(targetState);
81  
82          // Transform PVT from target's LOF to reference inertial frame
83          final Transform lofToInertial =
84                          getLof().transformFromInertial(targetState.getDate(),
85                                                         targetState.getPVCoordinates()).getInverse();
86          final TimeStampedPVCoordinates pvInertial = lofToInertial.transformPVCoordinates(chaserPVTLOF);
87  
88          // Transform PVT from reference inertial frame to desired output frame
89          final Transform inertialToOutputFrame = targetState.getFrame().getTransformTo(outputFrame,
90                                                                                        targetState.getDate());
91          return inertialToOutputFrame.transformPVCoordinates(pvInertial);
92      }
93  
94      /**
95       * Get the chaser state relative to a target, in target's LVLH LOF.
96       *
97       * @param spacecraftState spacecraft state to which additional data should correspond
98       * @return chaser Cartesian state in target's LVLH Local Orbital Frame.
99       */
100     @Override
101     default double[] getAdditionalData(final SpacecraftState spacecraftState) {
102 
103         // Extract chaser PVT in target's LOF
104         final TimeStampedPVCoordinates pvt = extractChaserPVT(spacecraftState);
105 
106         // Return a double[] to comply with
107         return new double[] {
108                         pvt.getPosition().getX(), pvt.getPosition().getY(), pvt.getPosition().getZ(),
109                         pvt.getVelocity().getX(), pvt.getVelocity().getY(), pvt.getVelocity().getZ()
110         };
111     }
112 
113     /**
114      * Get orbit of the target.
115      *
116      * @return orbit of the target
117      */
118     Orbit getTargetOrbit();
119 
120     /**
121      * Set orbit of the target.
122      *
123      * @param targetOrbit orbit of the target
124      */
125     void setTargetOrbit(Orbit targetOrbit);
126 
127     /**
128      * CW doesn't use true anomaly, so default is a no-op Set the true anomaly of the target.
129      *
130      * @param trueAnomaly true anomaly of the target
131      */
132     default void setTargetTrueAnomaly(final double trueAnomaly) {
133     }
134 }