1   /* Copyright 2002-2024 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.files.ccsds.ndm.odm.ocm;
19  
20  import java.util.Collections;
21  import java.util.List;
22  
23  import org.hipparchus.geometry.euclidean.threed.Vector3D;
24  import org.orekit.errors.OrekitException;
25  import org.orekit.errors.OrekitMessages;
26  import org.orekit.files.ccsds.definitions.BodyFacade;
27  import org.orekit.files.ccsds.definitions.DutyCycleType;
28  import org.orekit.files.ccsds.definitions.FrameFacade;
29  import org.orekit.files.ccsds.definitions.OrbitRelativeFrame;
30  import org.orekit.files.ccsds.definitions.SpacecraftBodyFrame;
31  import org.orekit.files.ccsds.section.CommentsContainer;
32  import org.orekit.time.AbsoluteDate;
33  import org.orekit.utils.units.Unit;
34  
35  /** Metadata for maneuver history.
36   * @author Luc Maisonobe
37   * @since 11.0
38   */
39  public class OrbitManeuverHistoryMetadata extends CommentsContainer {
40  
41      /** Default duty cycle type.
42       * @since 12.0
43       */
44      public static final DutyCycleType DEFAULT_DC_TYPE = DutyCycleType.CONTINUOUS;
45  
46      /** Maneuver identification number. */
47      private String manID;
48  
49      /** Identification number of previous maneuver. */
50      private String manPrevID;
51  
52      /** Identification number of next maneuver. */
53      private String manNextID;
54  
55      /** Basis of this maneuver history data. */
56      private ManBasis manBasis;
57  
58      /** Identification number of the orbit determination or simulation upon which this maneuver is based. */
59      private String manBasisID;
60  
61      /** Identifier of the device used for this maneuver. */
62      private String manDeviceID;
63  
64      /** Completion time of previous maneuver. */
65      private AbsoluteDate manPrevEpoch;
66  
67      /** Start time of next maneuver. */
68      private AbsoluteDate manNextEpoch;
69  
70      /** Reference frame of the maneuver. */
71      private FrameFacade manReferenceFrame;
72  
73      /** Epoch of the maneuver reference frame. */
74      private AbsoluteDate manFrameEpoch;
75  
76      /** Purposes of the maneuver. */
77      private List<String> manPurpose;
78  
79      /** Prediction source on which this maneuver is based. */
80      private String manPredSource;
81  
82      /** Origin of maneuver gravitational assist body. */
83      private BodyFacade gravitationalAssist;
84  
85      /** Type of duty cycle. */
86      private DutyCycleType dcType;
87  
88      /** Start time of duty cycle-based maneuver window. */
89      private AbsoluteDate dcWindowOpen;
90  
91      /** End time of duty cycle-based maneuver window. */
92      private AbsoluteDate dcWindowClose;
93  
94      /** Minimum number of "ON" duty cycles. */
95      private int dcMinCycles;
96  
97      /** Maximum number of "ON" duty cycles. */
98      private int dcMaxCycles;
99  
100     /** Start time of initial duty cycle-based maneuver execution. */
101     private AbsoluteDate dcExecStart;
102 
103     /** End time of final duty cycle-based maneuver execution. */
104     private AbsoluteDate dcExecStop;
105 
106     /** Duty cycle thrust reference time. */
107     private AbsoluteDate dcRefTime;
108 
109     /** Duty cycle pulse "ON" duration. */
110     private double dcTimePulseDuration;
111 
112     /** Duty cycle elapsed time between start of a pulse and start of next pulse. */
113     private double dcTimePulsePeriod;
114 
115     /** Reference direction for triggering duty cycle. */
116     private Vector3D dcRefDir;
117 
118     /** Spacecraft body frame in which {@link #dcBodyTrigger} is specified. */
119     private SpacecraftBodyFrame dcBodyFrame;
120 
121     /** Direction in {@link #dcBodyFrame body frame} for triggering duty cycle. */
122     private Vector3D dcBodyTrigger;
123 
124     /** Phase angle of pulse start. */
125     private double dcPhaseStartAngle;
126 
127     /** Phase angle of pulse stop. */
128     private double dcPhaseStopAngle;
129 
130     /** Maneuver elements of information. */
131     private List<ManeuverFieldType> manComposition;
132 
133     /** Units of covariance element set. */
134     private List<Unit> manUnits;
135 
136     /** Simple constructor.
137      * @param epochT0 T0 epoch from file metadata
138      */
139     public OrbitManeuverHistoryMetadata(final AbsoluteDate epochT0) {
140         // we don't call the setXxx() methods in order to avoid
141         // calling refuseFurtherComments as a side effect
142         manBasis            = ManBasis.PLANNED;
143         manReferenceFrame   = new FrameFacade(null, null,
144                                               OrbitRelativeFrame.TNW_INERTIAL, null,
145                                               OrbitRelativeFrame.TNW_INERTIAL.name());
146         manFrameEpoch       = epochT0;
147         manPurpose          = Collections.emptyList();
148         dcType              = DEFAULT_DC_TYPE;
149         dcMinCycles         = -1;
150         dcMaxCycles         = -1;
151         dcTimePulseDuration = Double.NaN;
152         dcTimePulsePeriod   = Double.NaN;
153     }
154 
155     /** {@inheritDoc} */
156     @Override
157     public void validate(final double version) {
158         super.validate(version);
159         checkNotNull(manID,          OrbitManeuverHistoryMetadataKey.MAN_ID.name());
160         checkNotNull(manDeviceID,    OrbitManeuverHistoryMetadataKey.MAN_DEVICE_ID.name());
161 
162         if (dcType != DutyCycleType.CONTINUOUS) {
163             checkNotNull(dcWindowOpen,       OrbitManeuverHistoryMetadataKey.DC_WIN_OPEN.name());
164             checkNotNull(dcWindowClose,      OrbitManeuverHistoryMetadataKey.DC_WIN_CLOSE.name());
165             checkNotNull(dcExecStart,        OrbitManeuverHistoryMetadataKey.DC_EXEC_START.name());
166             checkNotNull(dcExecStop,         OrbitManeuverHistoryMetadataKey.DC_EXEC_STOP.name());
167             checkNotNull(dcRefTime,          OrbitManeuverHistoryMetadataKey.DC_REF_TIME.name());
168             checkNotNaN(dcTimePulseDuration, OrbitManeuverHistoryMetadataKey.DC_TIME_PULSE_DURATION.name());
169             checkNotNaN(dcTimePulsePeriod,   OrbitManeuverHistoryMetadataKey.DC_TIME_PULSE_PERIOD.name());
170         }
171         if (dcType == DutyCycleType.TIME_AND_ANGLE) {
172             checkNotNull(dcRefDir,           OrbitManeuverHistoryMetadataKey.DC_REF_DIR.name());
173             checkNotNull(dcBodyFrame,        OrbitManeuverHistoryMetadataKey.DC_BODY_FRAME.name());
174             checkNotNull(dcBodyTrigger,      OrbitManeuverHistoryMetadataKey.DC_BODY_TRIGGER.name());
175             checkNotNull(dcPhaseStartAngle,  OrbitManeuverHistoryMetadataKey.DC_PA_START_ANGLE.name());
176             checkNotNull(dcPhaseStopAngle,   OrbitManeuverHistoryMetadataKey.DC_PA_STOP_ANGLE.name());
177         }
178 
179         checkNotNull(manComposition, OrbitManeuverHistoryMetadataKey.MAN_COMPOSITION.name());
180         if (!manComposition.get(0).isTime()) {
181             throw new OrekitException(OrekitMessages.CCSDS_MANEUVER_MISSING_TIME, manID);
182         }
183         final int firstNonTime = (manComposition.size() > 1 && manComposition.get(1).isTime()) ? 2 : 1;
184 
185         if (manUnits != null) {
186             if (manUnits.size() != manComposition.size() - firstNonTime) {
187                 throw new OrekitException(OrekitMessages.CCSDS_MANEUVER_UNITS_WRONG_NB_COMPONENTS,
188                                           manID);
189             }
190             for (int i = 0; i < manUnits.size(); ++i) {
191                 manComposition.get(firstNonTime + i).checkUnit(manUnits.get(i));
192             }
193         }
194     }
195 
196     /** Check if a field is a time field.
197      * @param Ma
198      */
199     /** Get maneuver identification number.
200      * @return maneuver identification number
201      */
202     public String getManID() {
203         return manID;
204     }
205 
206     /** Set maneuver identification number.
207      * @param manID maneuver identification number
208      */
209     public void setManID(final String manID) {
210         refuseFurtherComments();
211         this.manID = manID;
212     }
213 
214     /** Get identification number of previous maneuver.
215      * @return identification number of previous maneuver
216      */
217     public String getManPrevID() {
218         return manPrevID;
219     }
220 
221     /** Set identification number of previous maneuver.
222      * @param manPrevID identification number of previous maneuver
223      */
224     public void setManPrevID(final String manPrevID) {
225         refuseFurtherComments();
226         this.manPrevID = manPrevID;
227     }
228 
229     /** Get identification number of next maneuver.
230      * @return identification number of next maneuver
231      */
232     public String getManNextID() {
233         return manNextID;
234     }
235 
236     /** Set identification number of next maneuver.
237      * @param manNextID identification number of next maneuver
238      */
239     public void setManNextID(final String manNextID) {
240         refuseFurtherComments();
241         this.manNextID = manNextID;
242     }
243 
244     /** Get basis of this maneuver history data.
245      * @return basis of this maneuver history data
246      */
247     public ManBasis getManBasis() {
248         return manBasis;
249     }
250 
251     /** Set basis of this maneuver history data.
252      * @param manBasis basis of this maneuver history data
253      */
254     public void setManBasis(final ManBasis manBasis) {
255         refuseFurtherComments();
256         this.manBasis = manBasis;
257     }
258 
259     /** Get identification number of the orbit determination or simulation upon which this maneuver is based.
260      * @return identification number of the orbit determination or simulation upon which this maneuver is based
261      */
262     public String getManBasisID() {
263         return manBasisID;
264     }
265 
266     /** Set identification number of the orbit determination or simulation upon which this maneuver is based.
267      * @param manBasisID identification number of the orbit determination or simulation upon which this maneuver is based
268      */
269     public void setManBasisID(final String manBasisID) {
270         refuseFurtherComments();
271         this.manBasisID = manBasisID;
272     }
273 
274     /** Get identifier of the device used for this maneuver.
275      * @return identifier of the device used for this maneuver
276      */
277     public String getManDeviceID() {
278         return manDeviceID;
279     }
280 
281     /** Set identifier of the device used for this maneuver.
282      * @param manDeviceID identifier of the device used for this maneuver
283      */
284     public void setManDeviceID(final String manDeviceID) {
285         refuseFurtherComments();
286         this.manDeviceID = manDeviceID;
287     }
288 
289     /** Get completion time of previous maneuver.
290      * @return completion time of previous maneuver
291      */
292     public AbsoluteDate getManPrevEpoch() {
293         return manPrevEpoch;
294     }
295 
296     /** Set completion time of previous maneuver.
297      * @param manPrevEpoch completion time of previous maneuver
298      */
299     public void setManPrevEpoch(final AbsoluteDate manPrevEpoch) {
300         refuseFurtherComments();
301         this.manPrevEpoch = manPrevEpoch;
302     }
303 
304     /** Get start time of next maneuver.
305      * @return start time of next maneuver
306      */
307     public AbsoluteDate getManNextEpoch() {
308         return manNextEpoch;
309     }
310 
311     /** Set start time of next maneuver.
312      * @param manNextEpoch start time of next maneuver
313      */
314     public void setManNextEpoch(final AbsoluteDate manNextEpoch) {
315         refuseFurtherComments();
316         this.manNextEpoch = manNextEpoch;
317     }
318 
319     /** Get the purposes of the maneuver.
320      * @return purposes of the maneuver
321      */
322     public List<String> getManPurpose() {
323         return manPurpose;
324     }
325 
326     /** Set the purposes of the maneuver.
327      * @param manPurpose purposes of the maneuver
328      */
329     public void setManPurpose(final List<String> manPurpose) {
330         this.manPurpose = manPurpose;
331     }
332 
333     /** Get prediction source on which this maneuver is based.
334      * @return prediction source on which this maneuver is based
335      */
336     public String getManPredSource() {
337         return manPredSource;
338     }
339 
340     /** Set prediction source on which this maneuver is based.
341      * @param manPredSource prediction source on which this maneuver is based
342      */
343     public void setManPredSource(final String manPredSource) {
344         refuseFurtherComments();
345         this.manPredSource = manPredSource;
346     }
347 
348     /** Get reference frame of the maneuver.
349      * @return reference frame of the maneuver
350      */
351     public FrameFacade getManReferenceFrame() {
352         return manReferenceFrame;
353     }
354 
355     /** Set reference frame of the maneuver.
356      * @param manReferenceFrame the reference frame to be set
357      */
358     public void setManReferenceFrame(final FrameFacade manReferenceFrame) {
359         refuseFurtherComments();
360         this.manReferenceFrame = manReferenceFrame;
361     }
362 
363     /** Get epoch of the {@link #getManReferenceFrame() maneuver reference frame}.
364      * @return epoch of the {@link #getManReferenceFrame() maneuver reference frame}
365      */
366     public AbsoluteDate getManFrameEpoch() {
367         return manFrameEpoch;
368     }
369 
370     /** Set epoch of the {@link #getManReferenceFrame() maneuver reference frame}.
371      * @param manFrameEpoch epoch of the {@link #getManReferenceFrame() maneuver reference frame}
372      */
373     public void setManFrameEpoch(final AbsoluteDate manFrameEpoch) {
374         refuseFurtherComments();
375         this.manFrameEpoch = manFrameEpoch;
376     }
377 
378     /** Get the origin of gravitational assist.
379      * @return the origin of gravitational assist.
380      */
381     public BodyFacade getGravitationalAssist() {
382         return gravitationalAssist;
383     }
384 
385     /** Set the origin of gravitational assist.
386      * @param gravitationalAssist origin of gravitational assist to be set
387      */
388     public void setGravitationalAssist(final BodyFacade gravitationalAssist) {
389         refuseFurtherComments();
390         this.gravitationalAssist = gravitationalAssist;
391     }
392 
393     /** Get type of duty cycle.
394      * @return type of duty cycle
395      */
396     public DutyCycleType getDcType() {
397         return dcType;
398     }
399 
400     /** Set type of duty cycle.
401      * @param dcType type of duty cycle
402      */
403     public void setDcType(final DutyCycleType dcType) {
404         this.dcType = dcType;
405     }
406 
407     /** Get the start time of duty cycle-based maneuver window.
408      * @return start time of duty cycle-based maneuver window
409      */
410     public AbsoluteDate getDcWindowOpen() {
411         return dcWindowOpen;
412     }
413 
414     /** Set the start time of duty cycle-based maneuver window.
415      * @param dcWindowOpen start time of duty cycle-based maneuver window
416      */
417     public void setDcWindowOpen(final AbsoluteDate dcWindowOpen) {
418         this.dcWindowOpen = dcWindowOpen;
419     }
420 
421     /** Get the end time of duty cycle-based maneuver window.
422      * @return end time of duty cycle-based maneuver window
423      */
424     public AbsoluteDate getDcWindowClose() {
425         return dcWindowClose;
426     }
427 
428     /** Set the end time of duty cycle-based maneuver window.
429      * @param dcWindowClose end time of duty cycle-based maneuver window
430      */
431     public void setDcWindowClose(final AbsoluteDate dcWindowClose) {
432         this.dcWindowClose = dcWindowClose;
433     }
434 
435     /** Get the minimum number of "ON" duty cycles.
436      * @return minimum number of "ON" duty cycles (-1 if not set)
437      */
438     public int getDcMinCycles() {
439         return dcMinCycles;
440     }
441 
442     /** Set the minimum number of "ON" duty cycles.
443      * @param dcMinCycles minimum number of "ON" duty cycles
444      */
445     public void setDcMinCycles(final int dcMinCycles) {
446         this.dcMinCycles = dcMinCycles;
447     }
448 
449     /** Get the maximum number of "ON" duty cycles.
450      * @return maximum number of "ON" duty cycles (-1 if not set)
451      */
452     public int getDcMaxCycles() {
453         return dcMaxCycles;
454     }
455 
456     /** Set the maximum number of "ON" duty cycles.
457      * @param dcMaxCycles maximum number of "ON" duty cycles
458      */
459     public void setDcMaxCycles(final int dcMaxCycles) {
460         this.dcMaxCycles = dcMaxCycles;
461     }
462 
463     /** Get the start time of initial duty cycle-based maneuver execution.
464      * @return start time of initial duty cycle-based maneuver execution
465      */
466     public AbsoluteDate getDcExecStart() {
467         return dcExecStart;
468     }
469 
470     /** Set the start time of initial duty cycle-based maneuver execution.
471      * @param dcExecStart start time of initial duty cycle-based maneuver execution
472      */
473     public void setDcExecStart(final AbsoluteDate dcExecStart) {
474         this.dcExecStart = dcExecStart;
475     }
476 
477     /** Get the end time of final duty cycle-based maneuver execution.
478      * @return end time of final duty cycle-based maneuver execution
479      */
480     public AbsoluteDate getDcExecStop() {
481         return dcExecStop;
482     }
483 
484     /** Set the end time of final duty cycle-based maneuver execution.
485      * @param dcExecStop end time of final duty cycle-based maneuver execution
486      */
487     public void setDcExecStop(final AbsoluteDate dcExecStop) {
488         this.dcExecStop = dcExecStop;
489     }
490 
491     /** Get duty cycle thrust reference time.
492      * @return duty cycle thrust reference time
493      */
494     public AbsoluteDate getDcRefTime() {
495         return dcRefTime;
496     }
497 
498     /** Set duty cycle thrust reference time.
499      * @param dcRefTime duty cycle thrust reference time
500      */
501     public void setDcRefTime(final AbsoluteDate dcRefTime) {
502         this.dcRefTime = dcRefTime;
503     }
504 
505     /** Get duty cycle pulse "ON" duration.
506      * @return duty cycle pulse "ON" duration
507      */
508     public double getDcTimePulseDuration() {
509         return dcTimePulseDuration;
510     }
511 
512     /** Set duty cycle pulse "ON" duration.
513      * @param dcTimePulseDuration duty cycle pulse "ON" duration
514      */
515     public void setDcTimePulseDuration(final double dcTimePulseDuration) {
516         this.dcTimePulseDuration = dcTimePulseDuration;
517     }
518 
519     /** Get duty cycle elapsed time between start of a pulse and start of next pulse.
520      * @return duty cycle elapsed time between start of a pulse and start of next pulse
521      */
522     public double getDcTimePulsePeriod() {
523         return dcTimePulsePeriod;
524     }
525 
526     /** Set duty cycle elapsed time between start of a pulse and start of next pulse.
527      * @param dcTimePulsePeriod duty cycle elapsed time between start of a pulse and start of next pulse
528      */
529     public void setDcTimePulsePeriod(final double dcTimePulsePeriod) {
530         this.dcTimePulsePeriod = dcTimePulsePeriod;
531     }
532 
533     /** Get reference direction for triggering duty cycle.
534      * @return reference direction for triggering duty cycle
535      */
536     public Vector3D getDcRefDir() {
537         return dcRefDir;
538     }
539 
540     /** Set reference direction for triggering duty cycle.
541      * @param dcRefDir reference direction for triggering duty cycle
542      */
543     public void setDcRefDir(final Vector3D dcRefDir) {
544         this.dcRefDir = dcRefDir;
545     }
546 
547     /** Get spacecraft body frame in which {@link #getDcBodyTrigger()} is specified.
548      * @return spacecraft body frame in which {@link #getDcBodyTrigger()} is specified
549      */
550     public SpacecraftBodyFrame getDcBodyFrame() {
551         return dcBodyFrame;
552     }
553 
554     /** Set spacecraft body frame in which {@link #getDcBodyTrigger()} is specified.
555      * @param dcBodyFrame spacecraft body frame in which {@link #getDcBodyTrigger()} is specified
556      */
557     public void setDcBodyFrame(final SpacecraftBodyFrame dcBodyFrame) {
558         this.dcBodyFrame = dcBodyFrame;
559     }
560 
561     /** Get direction in {@link #getDcBodyFrame() body frame} for triggering duty cycle.
562      * @return direction in {@link #getDcBodyFrame() body frame} for triggering duty cycle
563      */
564     public Vector3D getDcBodyTrigger() {
565         return  dcBodyTrigger;
566     }
567 
568     /** Set direction in {@link #getDcBodyFrame() body frame} for triggering duty cycle.
569      * @param dcBodyTrigger direction in {@link #getDcBodyFrame() body frame} for triggering duty cycle
570      */
571     public void setDcBodyTrigger(final Vector3D dcBodyTrigger) {
572         this.dcBodyTrigger = dcBodyTrigger;
573     }
574 
575     /** Get phase angle of pulse start.
576      * @return phase angle of pulse start
577      */
578     public double getDcPhaseStartAngle() {
579         return dcPhaseStartAngle;
580     }
581 
582     /** Set phase angle of pulse start.
583      * @param dcPhaseStartAngle phase angle of pulse start
584      */
585     public void setDcPhaseStartAngle(final double dcPhaseStartAngle) {
586         this.dcPhaseStartAngle = dcPhaseStartAngle;
587     }
588 
589     /** Get phase angle of pulse stop.
590      * @return phase angle of pulse stop
591      */
592     public double getDcPhaseStopAngle() {
593         return dcPhaseStopAngle;
594     }
595 
596     /** Set phase angle of pulse stop.
597      * @param dcPhaseStopAngle phase angle of pulse stop
598      */
599     public void setDcPhaseStopAngle(final double dcPhaseStopAngle) {
600         this.dcPhaseStopAngle = dcPhaseStopAngle;
601     }
602 
603     /** Get maneuver elements of information.
604      * @return maneuver element of information
605      */
606     public List<ManeuverFieldType> getManComposition() {
607         return manComposition;
608     }
609 
610     /** Set maneuver element of information.
611      * @param manComposition maneuver element of information
612      */
613     public void setManComposition(final List<ManeuverFieldType> manComposition) {
614         refuseFurtherComments();
615         this.manComposition = manComposition;
616     }
617 
618     /** Get maneuver elements of information units.
619      * @return maneuver element of information units
620      */
621     public List<Unit> getManUnits() {
622         return manUnits;
623     }
624 
625     /** Set maneuver element of information units.
626      * @param manUnits maneuver element of information units
627      */
628     public void setManUnits(final List<Unit> manUnits) {
629         refuseFurtherComments();
630         this.manUnits = manUnits;
631     }
632 
633 }