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