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.opm;
19  
20  import java.util.List;
21  
22  import org.orekit.data.DataContext;
23  import org.orekit.files.ccsds.ndm.NdmConstituent;
24  import org.orekit.files.ccsds.ndm.odm.OdmCommonMetadata;
25  import org.orekit.files.ccsds.ndm.odm.OdmHeader;
26  import org.orekit.files.ccsds.section.Segment;
27  import org.orekit.orbits.CartesianOrbit;
28  import org.orekit.orbits.KeplerianOrbit;
29  import org.orekit.propagation.SpacecraftState;
30  import org.orekit.time.AbsoluteDate;
31  import org.orekit.time.TimeStamped;
32  import org.orekit.utils.IERSConventions;
33  import org.orekit.utils.TimeStampedPVCoordinates;
34  
35  /** This class gathers the informations present in the Orbital Parameter Message (OPM).
36   * @author sports
37   * @since 6.1
38   */
39  public class Opm extends NdmConstituent<OdmHeader, Segment<OdmCommonMetadata, OpmData>> implements TimeStamped {
40  
41      /** Root element for XML files. */
42      public static final String ROOT = "opm";
43  
44      /** Key for format version. */
45      public static final String FORMAT_VERSION_KEY = "CCSDS_OPM_VERS";
46  
47      /** Gravitational coefficient to use for building Cartesian/Keplerian orbits. */
48      private final double mu;
49  
50      /** Simple constructor.
51       * @param header file header
52       * @param segments file segments
53       * @param conventions IERS conventions
54       * @param dataContext used for creating frames, time scales, etc.
55       * @param mu gravitational coefficient to use for building Cartesian/Keplerian orbits
56       */
57      public Opm(final OdmHeader header, final List<Segment<OdmCommonMetadata, OpmData>> segments,
58                 final IERSConventions conventions, final DataContext dataContext,
59                 final double mu) {
60          super(header, segments, conventions, dataContext);
61          this.mu = mu;
62      }
63  
64      /** Get the file metadata.
65       * @return file metadata
66       */
67      public OdmCommonMetadata getMetadata() {
68          return getSegments().getFirst().getMetadata();
69      }
70  
71      /** Get the file data.
72       * @return file data
73       */
74      public OpmData getData() {
75          return getSegments().getFirst().getData();
76      }
77  
78      /** {@inheritDoc} */
79      @Override
80      public AbsoluteDate getDate() {
81          return getData().getStateVectorBlock().getEpoch();
82      }
83  
84      /** Get the number of maneuvers present in the OPM.
85       * @return the number of maneuvers
86       */
87      public int getNbManeuvers() {
88          return getData().getNbManeuvers();
89      }
90  
91      /** Get a list of all maneuvers.
92       * @return unmodifiable list of all maneuvers.
93       */
94      public List<Maneuver> getManeuvers() {
95          return getData().getManeuvers();
96      }
97  
98      /** Get a maneuver.
99       * @param index maneuver index, counting from 0
100      * @return maneuver
101      */
102     public Maneuver getManeuver(final int index) {
103         return getData().getManeuver(index);
104     }
105 
106     /** check whether the OPM contains at least one maneuver.
107      * @return true if OPM contains at least one maneuver false otherwise
108      */
109     public boolean hasManeuvers() {
110         return getData().hasManeuvers();
111     }
112 
113     /** Get the position/velocity coordinates contained in the OPM.
114      * @return the position/velocity coordinates contained in the OPM
115      */
116     public TimeStampedPVCoordinates getPVCoordinates() {
117         return getData().getStateVectorBlock().toTimeStampedPVCoordinates();
118     }
119 
120     /** Generate a Cartesian orbit.
121      * @return generated orbit
122      */
123     public CartesianOrbit generateCartesianOrbit() {
124         return new CartesianOrbit(getPVCoordinates(), getMetadata().getFrame(),
125                                   getData().getStateVectorBlock().getEpoch(),
126                                   mu);
127     }
128 
129     /** Generate a keplerian orbit.
130      * @return generated orbit
131      */
132     public KeplerianOrbit generateKeplerianOrbit() {
133         final OdmCommonMetadata metadata = getMetadata();
134         final OpmData        data     = getData();
135         if (data.getKeplerianElementsBlock().isPresent()) {
136             return data.getKeplerianElementsBlock().get().generateKeplerianOrbit(metadata.getFrame(), mu);
137         } else {
138             return new KeplerianOrbit(getPVCoordinates(), metadata.getFrame(),
139                                       data.getStateVectorBlock().getEpoch(),
140                                       mu);
141         }
142     }
143 
144     /** Generate spacecraft state from the {@link CartesianOrbit} generated by generateCartesianOrbit.
145      * @return the spacecraft state of the OPM
146      */
147     public SpacecraftState generateSpacecraftState() {
148         return new SpacecraftState(generateCartesianOrbit()).withMass(getData().getMass());
149     }
150 
151 }
152