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 package org.orekit.files.ccsds.ndm.adm.apm;
18
19 import java.util.Arrays;
20 import java.util.Optional;
21
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.orekit.annotation.Nullable;
24 import org.orekit.files.ccsds.definitions.FrameFacade;
25 import org.orekit.files.ccsds.section.CommentsContainer;
26 import org.orekit.time.AbsoluteDate;
27
28 /**
29 * Maneuver in an APM file.
30 * <p>
31 * Beware that the Orekit getters and setters all rely on SI units. The parsers
32 * and writers take care of converting these SI units into CCSDS mandatory units.
33 * The {@link org.orekit.utils.units.Unit Unit} class provides useful
34 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
35 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
36 * already use CCSDS units instead of the API SI units. The general-purpose
37 * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
38 * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
39 * (with an 's') also provide some predefined units. These predefined units and the
40 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
41 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
42 * what the parsers and writers use for the conversions.
43 * </p>
44 * @author Bryan Cazabonne
45 * @since 10.2
46 */
47 public class Maneuver extends CommentsContainer {
48
49 /** Epoch of start of maneuver . */
50 private AbsoluteDate epochStart;
51
52 /** Coordinate system for the torque vector. */
53 private FrameFacade frame;
54
55 /** Duration (value is 0 for impulsive maneuver). */
56 private double duration;
57
58 /** Torque vector (N.m). */
59 private final double[] torque;
60
61 /** Mass change during maneuver (kg).
62 * @since 12.0
63 */
64 @Nullable
65 private Double deltaMass;
66
67 /**
68 * Simple constructor.
69 */
70 public Maneuver() {
71 duration = Double.NaN;
72 torque = new double[3];
73 Arrays.fill(torque, Double.NaN);
74 }
75
76 /** {@inheritDoc} */
77 @Override
78 public void validate(final double version) {
79 super.validate(version);
80 checkNotNull(epochStart, ManeuverKey.MAN_EPOCH_START.name());
81 checkNotNaN(duration, ManeuverKey.MAN_DURATION.name());
82 checkNotNull(frame, ManeuverKey.MAN_REF_FRAME.name());
83 checkNotNaN(torque[0], ManeuverKey.MAN_TOR_1.name());
84 checkNotNaN(torque[1], ManeuverKey.MAN_TOR_2.name());
85 checkNotNaN(torque[2], ManeuverKey.MAN_TOR_3.name());
86 }
87
88 /**
89 * Get epoch start.
90 * @return epoch start
91 */
92 public AbsoluteDate getEpochStart() {
93 return epochStart;
94 }
95
96 /**
97 * Set epoch start.
98 * @param epochStart epoch start
99 */
100 public void setEpochStart(final AbsoluteDate epochStart) {
101 refuseFurtherComments();
102 this.epochStart = epochStart;
103 }
104
105 /**
106 * Get Coordinate system for the torque vector.
107 * @return coordinate system for the torque vector
108 */
109 public FrameFacade getFrame() {
110 return frame;
111 }
112
113 /**
114 * Set Coordinate system for the torque vector.
115 * @param frame coordinate system for the torque vector
116 */
117 public void setFrame(final FrameFacade frame) {
118 refuseFurtherComments();
119 this.frame = frame;
120 }
121
122 /**
123 * Get duration (value is 0 for impulsive maneuver).
124 * @return duration (value is 0 for impulsive maneuver)
125 */
126 public double getDuration() {
127 return duration;
128 }
129
130 /**
131 * Set duration (value is 0 for impulsive maneuver).
132 * @param duration duration (value is 0 for impulsive maneuver)
133 */
134 public void setDuration(final double duration) {
135 refuseFurtherComments();
136 this.duration = duration;
137 }
138
139 /**
140 * Get the torque vector (N.m).
141 * @return torque vector
142 */
143 public Vector3D getTorque() {
144 return new Vector3D(torque);
145 }
146
147 /**
148 * Set the torque vector (N.m).
149 * @param index vector component index (counting from 0)
150 * @param value component value
151 */
152 public void setTorque(final int index, final double value) {
153 refuseFurtherComments();
154 this.torque[index] = value;
155 }
156
157 /**
158 * Get mass change during maneuver.
159 * @return mass change during maneuver (kg, negative)
160 * @since 12.0
161 */
162 public Optional<Double> getDeltaMass() {
163 return Optional.ofNullable(deltaMass);
164 }
165
166 /**
167 * Set mass change during maneuver.
168 * @param deltaMass mass change during maneuver (kg)
169 * @since 12.0
170 */
171 public void setDeltaMass(final double deltaMass) {
172 refuseFurtherComments();
173 this.deltaMass = deltaMass;
174 }
175
176 }