1   /* Copyright 2022-2025 Luc Maisonobe
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.files.ccsds.ndm.adm.acm;
19  
20  import org.hipparchus.geometry.euclidean.threed.Rotation;
21  import org.hipparchus.geometry.euclidean.threed.Vector3D;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  import org.orekit.files.ccsds.definitions.FrameFacade;
25  import org.orekit.files.ccsds.section.CommentsContainer;
26  
27  /** Maneuver entry.
28   * <p>
29   * Beware that the Orekit getters and setters all rely on SI units. The parsers
30   * and writers take care of converting these SI units into CCSDS mandatory units.
31   * The {@link org.orekit.utils.units.Unit Unit} class provides useful
32   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
33   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
34   * already use CCSDS units instead of the API SI units. The general-purpose
35   * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
36   * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
37   * (with an 's') also provide some predefined units. These predefined units and the
38   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
39   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
40   * what the parsers and writers use for the conversions.
41   * </p>
42   * @author Luc Maisonobe
43   * @since 12.0
44   */
45  public class AttitudeManeuver extends CommentsContainer {
46  
47      /** Maneuver identification number. */
48      private String id;
49  
50      /** Identification number of previous maneuver. */
51      private String prevID;
52  
53      /** Purpose of the maneuver. */
54      private String manPurpose;
55  
56      /** Start time of actual maneuver, relative to t₀. */
57      private double beginTime;
58  
59      /** End time of actual maneuver, relative to t₀. */
60      private double endTime;
61  
62      /** Duration. */
63      private double duration;
64  
65      /** Actuator used. */
66      private String actuatorUsed;
67  
68      /** Target momentum (if purpose is momentum desaturation). */
69      private Vector3D targetMomentum;
70  
71      /** Reference frame for {@link #targetMomentum}. */
72      private FrameFacade targetMomFrame;
73  
74      /** Target attitude (if purpose is attitude adjustment). */
75      private Rotation targetAttitude;
76  
77      /** Target spin rate (if purpose is spin rate adjustment). */
78      private double targetSpinRate;
79  
80      /** Build an uninitialized maneuver.
81       */
82      public AttitudeManeuver() {
83          beginTime      = Double.NaN;
84          endTime        = Double.NaN;
85          duration       = Double.NaN;
86          targetSpinRate = Double.NaN;
87      }
88  
89      /** {@inheritDoc} */
90      @Override
91      public void validate(final double version) {
92          checkNotNull(manPurpose, AttitudeManeuverKey.MAN_PURPOSE.name());
93          checkNotNaN(beginTime,   AttitudeManeuverKey.MAN_BEGIN_TIME.name());
94          if (!Double.isNaN(endTime + duration)) {
95              throw new OrekitException(OrekitMessages.CCSDS_INCOMPATIBLE_KEYS_BOTH_USED,
96                                        AttitudeManeuverKey.MAN_END_TIME,
97                                        AttitudeManeuverKey.MAN_DURATION);
98          }
99          if (targetMomFrame != null) {
100             checkNotNull(targetMomentum, AttitudeManeuverKey.TARGET_MOMENTUM.name());
101         }
102     }
103 
104     /** Get maneuver identification number.
105      * @return maneuver identification number
106      */
107     public String getID() {
108         return id;
109     }
110 
111     /** Set maneuver identification number.
112      * @param manId maneuver identification number
113      */
114     public void setID(final String manId) {
115         refuseFurtherComments();
116         this.id = manId;
117     }
118 
119     /** Get identification number of previous maneuver.
120      * @return identification number of previous maneuver
121      */
122     public String getPrevID() {
123         return prevID;
124     }
125 
126     /** Set identification number of previous maneuver.
127      * @param prevID identification number of previous maneuver
128      */
129     public void setPrevID(final String prevID) {
130         refuseFurtherComments();
131         this.prevID = prevID;
132     }
133 
134     /** Get purpose of maneuver.
135      * @return purpose of maneuver
136      */
137     public String getManPurpose() {
138         return manPurpose;
139     }
140 
141     /** Set purpose of maneuver.
142      * @param manPurpose purpose of maneuver
143      */
144     public void setManPurpose(final String manPurpose) {
145         refuseFurtherComments();
146         this.manPurpose = manPurpose;
147     }
148 
149     /** Get start time of actual maneuver, relative to t₀.
150      * @return start time of actual maneuver, relative to t₀
151      */
152     public double getBeginTime() {
153         return beginTime;
154     }
155 
156     /** Set start time of actual maneuver, relative to t₀.
157      * @param beginTime start time of actual maneuver, relative to t₀
158      */
159     public void setBeginTime(final double beginTime) {
160         this.beginTime = beginTime;
161     }
162 
163     /** Get end time of actual maneuver, relative to t₀.
164      * @return end time of actual maneuver, relative to t₀
165      */
166     public double getEndTime() {
167         return endTime;
168     }
169 
170     /** Set end time of actual maneuver, relative to t₀.
171      * @param endTime end time of actual maneuver, relative to t₀
172      */
173     public void setEndTime(final double endTime) {
174         this.endTime = endTime;
175     }
176 
177     /** Get duration.
178      * @return duration
179      */
180     public double getDuration() {
181         return duration;
182     }
183 
184     /** Set duration.
185      * @param duration duration
186      */
187     public void setDuration(final double duration) {
188         this.duration = duration;
189     }
190 
191     /** Get the actuator used.
192      * @return actuator used
193      */
194     public String getActuatorUsed() {
195         return actuatorUsed;
196     }
197 
198     /** Set actuator used.
199      * @param actuatorUsed actuator used
200      */
201     public void setActuatorUsed(final String actuatorUsed) {
202         this.actuatorUsed = actuatorUsed;
203     }
204 
205     /** Get target momentum (if purpose is momentum desaturation).
206      * @return target momentum
207      */
208     public Vector3D getTargetMomentum() {
209         return targetMomentum;
210     }
211 
212     /** Set target momentum (if purpose is momentum desaturation).
213      * @param targetMomentum target momentum
214      */
215     public void setTargetMomentum(final Vector3D targetMomentum) {
216         this.targetMomentum = targetMomentum;
217     }
218 
219     /** Get reference frame for {@link #getTargetMomentum()}.
220      * @return reference frame for {@link #getTargetMomentum()}
221      */
222     public FrameFacade getTargetMomFrame() {
223         return targetMomFrame;
224     }
225 
226     /** Set reference frame for {@link #getTargetMomentum()}.
227      * @param targetMomFrame reference frame for {@link #getTargetMomentum()}
228      */
229     public void setTargetMomFrame(final FrameFacade targetMomFrame) {
230         this.targetMomFrame = targetMomFrame;
231     }
232 
233     /** Get target attitude (if purpose is attitude adjustment).
234      * @return target attitude
235      */
236     public Rotation getTargetAttitude() {
237         return targetAttitude;
238     }
239 
240     /** Set target attitude (if purpose is attitude adjustment).
241      * @param targetAttitude target attitude
242      */
243     public void setTargetAttitude(final Rotation targetAttitude) {
244         this.targetAttitude = targetAttitude;
245     }
246 
247     /** Get target spin rate (if purpose is spin rate adjustment).
248      * @return target spin rate
249      */
250     public double getTargetSpinRate() {
251         return targetSpinRate;
252     }
253 
254     /** Set target spin rate (if purpose is spin rate adjustment).
255      * @param targetSpinRate target spin rate
256      */
257     public void setTargetSpinRate(final double targetSpinRate) {
258         this.targetSpinRate = targetSpinRate;
259     }
260 
261 }