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