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