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;
19
20 import java.util.function.Supplier;
21
22 import org.hipparchus.linear.MatrixUtils;
23 import org.hipparchus.linear.RealMatrix;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.files.ccsds.definitions.CcsdsFrameMapper;
27 import org.orekit.files.ccsds.definitions.FrameFacade;
28 import org.orekit.files.ccsds.section.CommentsContainer;
29 import org.orekit.files.ccsds.section.Data;
30 import org.orekit.frames.Frame;
31 import org.orekit.time.AbsoluteDate;
32
33 /** Container for OPM/OMM/OCM Cartesian covariance matrix.
34 * <p>
35 * Beware that the Orekit getters and setters all rely on SI units. The parsers
36 * and writers take care of converting these SI units into CCSDS mandatory units.
37 * The {@link org.orekit.utils.units.Unit Unit} class provides useful
38 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
39 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
40 * already use CCSDS units instead of the API SI units. The general-purpose
41 * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
42 * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
43 * (with an 's') also provide some predefined units. These predefined units and the
44 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
45 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
46 * what the parsers and writers use for the conversions.
47 * </p>
48 * @author sports
49 * @since 6.1
50 */
51 public class CartesianCovariance extends CommentsContainer implements Data {
52
53 /** Labels for matrix row/columns. */
54 private static final String[] LABELS = {
55 "X", "Y", "Z", "X_DOT", "Y_DOT", "Z_DOT"
56 };
57
58 /** Supplier for default reference frame. */
59 private final Supplier<FrameFacade> defaultFrameSupplier;
60
61 /** For creating a {@link Frame}. */
62 private final CcsdsFrameMapper frameMapper;
63
64 /** Matrix epoch. */
65 private AbsoluteDate epoch;
66
67 /** Reference frame in which data are given. */
68 private FrameFacade referenceFrame;
69
70 /** Position/Velocity covariance matrix. */
71 private final RealMatrix covarianceMatrix;
72
73 /**
74 * Create an empty data set.
75 *
76 * @param defaultFrameSupplier supplier for default reference frame if no
77 * frame is specified in the CCSDS message
78 * @param frameMapper for creating a {@link Frame}.
79 * @since 13.1.5
80 */
81 public CartesianCovariance(final Supplier<FrameFacade> defaultFrameSupplier,
82 final CcsdsFrameMapper frameMapper) {
83 this.defaultFrameSupplier = defaultFrameSupplier;
84 this.frameMapper = frameMapper;
85 covarianceMatrix = MatrixUtils.createRealMatrix(6, 6);
86 for (int i = 0; i < covarianceMatrix.getRowDimension(); ++i) {
87 for (int j = 0; j <= i; ++j) {
88 covarianceMatrix.setEntry(i, j, Double.NaN);
89 }
90 }
91 }
92
93 /** {@inheritDoc} */
94 @Override
95 public void validate(final double version) {
96 super.validate(version);
97 checkNotNull(epoch, CartesianCovarianceKey.EPOCH.name());
98 for (int i = 0; i < covarianceMatrix.getRowDimension(); ++i) {
99 for (int j = 0; j <= i; ++j) {
100 if (Double.isNaN(covarianceMatrix.getEntry(i, j))) {
101 throw new OrekitException(OrekitMessages.CCSDS_MISSING_KEYWORD,
102 "C" + LABELS[i] + "_" + LABELS[j]);
103 }
104 }
105 }
106 }
107
108 /** Get matrix epoch.
109 * @return matrix epoch
110 */
111 public AbsoluteDate getEpoch() {
112 return epoch;
113 }
114
115 /** Set matrix epoch.
116 * @param epoch matrix epoch
117 */
118 public void setEpoch(final AbsoluteDate epoch) {
119 refuseFurtherComments();
120 this.epoch = epoch;
121 }
122
123 /**
124 * Get the reference frame.
125 *
126 * @return The reference frame specified by the {@code COV_REF_FRAME} keyword
127 * or inherited from metadata
128 */
129 public FrameFacade getReferenceFrame() {
130 return referenceFrame == null ? defaultFrameSupplier.get() : referenceFrame;
131 }
132
133 /** Set the reference frame in which data are given.
134 * @param referenceFrame the reference frame to be set
135 */
136 public void setReferenceFrame(final FrameFacade referenceFrame) {
137 refuseFurtherComments();
138 this.referenceFrame = referenceFrame;
139 }
140
141 /**
142 * Get the mapping between a CCSDS frame and a {@link Frame}.
143 *
144 * @return the frame mapper.
145 * @since 13.1.5
146 */
147 public CcsdsFrameMapper getFrameMapper() {
148 return frameMapper;
149 }
150
151 /**
152 * Get the frame in which this covariance matrix is defined. Note that only
153 * the orientation of the returned frame is significant, the position of the
154 * returned frame is irrelevant and should be ignored.
155 *
156 * @return Orekit frame for this covariance matrix.
157 * @see #getReferenceFrame()
158 * @see #getFrameMapper()
159 * @since 13.1.5
160 */
161 public Frame getFrame() {
162 // OEM, OMM, and OPM don't allow a COV_FRAME_EPOCH, but OCM does.
163 // This class is not used for OCM, which allows non-Cartesian covariance
164 return getFrameMapper().buildCcsdsFrame(getReferenceFrame(), null);
165 }
166
167 /** Get the Position/Velocity covariance matrix.
168 * @return the Position/Velocity covariance matrix
169 */
170 public RealMatrix getCovarianceMatrix() {
171 return covarianceMatrix;
172 }
173
174 /** Set an entry in the Position/Velocity covariance matrix.
175 * <p>
176 * Both m(j, k) and m(k, j) are set.
177 * </p>
178 * @param j row index (must be between 0 and 5 (inclusive)
179 * @param k column index (must be between 0 and 5 (inclusive)
180 * @param entry value of the matrix entry
181 */
182 public void setCovarianceMatrixEntry(final int j, final int k, final double entry) {
183 refuseFurtherComments();
184 covarianceMatrix.setEntry(j, k, entry);
185 covarianceMatrix.setEntry(k, j, entry);
186 }
187
188 }