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.cdm;
18
19 import java.util.List;
20
21 import org.orekit.bodies.CelestialBody;
22 import org.orekit.data.DataContext;
23 import org.orekit.errors.OrekitException;
24 import org.orekit.errors.OrekitMessages;
25 import org.orekit.files.ccsds.definitions.BodyFacade;
26 import org.orekit.files.ccsds.definitions.CcsdsFrameMapper;
27 import org.orekit.files.ccsds.definitions.CelestialBodyFrame;
28 import org.orekit.files.ccsds.definitions.FrameFacade;
29 import org.orekit.files.ccsds.definitions.TimeSystem;
30 import org.orekit.files.ccsds.definitions.YesNoUnknown;
31 import org.orekit.files.ccsds.ndm.odm.ocm.ObjectType;
32 import org.orekit.files.ccsds.section.Metadata;
33 import org.orekit.frames.Frame;
34
35 /**
36 * This class gathers the meta-data present in the Conjunction Data Message (CDM).
37 * @author Melina Vanel
38 * @since 11.2
39 */
40 public class CdmMetadata extends Metadata {
41
42 /** CDM relative metadata. */
43 private CdmRelativeMetadata relativeMetadata;
44
45 /** Refering to object 1 or 2. */
46 private String object;
47
48 /** Unique satellite identification designator for the object. */
49 private String objectDesignator;
50
51 /** Specification of satellite catalog source. */
52 private String catalogName;
53
54 /** Object name. */
55 private String objectName;
56
57 /** International designator for the object as assigned by the UN Committee
58 * on Space Research (COSPAR) and the US National Space Science Data Center (NSSDC). */
59 private String internationalDesignator;
60
61 /** Type of object. */
62 private ObjectType objectType;
63
64 /** Operator contact position for the space object. */
65 private String operatorContact;
66
67 /** Operator organization for the space object. */
68 private String operatorOrganization;
69
70 /** Operator phone for the space object. */
71 private String operatorPhone;
72
73 /** Operator email for the space object. */
74 private String operatorEmail;
75
76 /** Unique identifier of Orbit Data Message(s) that are linked (relevant) to this Conjunction Data Message. */
77 private String odmMsgLink;
78
79 /** Unique identifier of Attitude Data Message(s) that are linked (relevant) to this Conjunction Data Message. */
80 private String admMsgLink;
81
82 /** Unique name of the external ephemeris file used for the object or NONE. */
83 private String ephemName;
84
85 /** Flag indicating whether new tracking observations are anticipated prior to the issue of the next CDM associated with the event
86 * specified by CONJUNCTION_ID. */
87 private YesNoUnknown obsBeforeNextMessage;
88
89 /** Operator email for the space object. */
90 private CovarianceMethod covarianceMethod;
91
92 /** Maneuver capacity. */
93 private Maneuvrable maneuverable;
94
95 /** Central body around which Object1 and 2 are orbiting. */
96 private BodyFacade orbitCenter;
97
98 /** Reference frame in which state vector data are given. */
99 private FrameFacade refFrame;
100
101 /** Gravity model name. */
102 private String gravityModel;
103
104 /** Degree of the gravity model. */
105 private int gravityDegree;
106
107 /** Order of the gravity model. */
108 private int gravityOrder;
109
110 /** Name of atmospheric model. */
111 private String atmosphericModel;
112
113 /** N-body perturbation bodies. */
114 private List<BodyFacade> nBodyPerturbations;
115
116 /** Is solar radiation pressure taken into account or not ? STANDARD CCSDS saying YES/NO choice and optional */
117 private YesNoUnknown isSolarRadPressure;
118
119 /** Is solid Earth and ocean tides taken into account or not. STANDARD CCSDS saying YES/NO choice and optional */
120 private YesNoUnknown isEarthTides;
121
122 /** Is in-track thrust modelling used or not. STANDARD CCSDS saying YES/NO choice and optional */
123 private YesNoUnknown isIntrackThrustModeled;
124
125 /** The source from which the covariance data used in the report for both Object 1 and Object 2 originates. */
126 private String covarianceSource;
127
128 /** Flag indicating the type of alternate covariance information provided. */
129 private AltCovarianceType altCovType;
130
131 /** Reference frame in which the alternate covariance data are given. */
132 private FrameFacade altCovRefFrame;
133
134 /** Simple constructor.
135 *
136 * @param dataContext data context
137 * @param frameMapper for creating an Orekit {@link Frame}.
138 * @since 13.1.5
139 */
140 public CdmMetadata(final DataContext dataContext,
141 final CcsdsFrameMapper frameMapper) {
142 super(null, frameMapper);
143 final CelestialBody earth = dataContext.getCelestialBodies().getEarth();
144 orbitCenter = new BodyFacade(earth.getName().toUpperCase(), earth);
145 }
146
147 /** {@inheritDoc} */
148 @Override
149 public void validate(final double version) {
150 // We only check values that are mandatory in a cdm file
151 checkNotNull(object, CdmMetadataKey.OBJECT.name());
152 checkNotNull(objectDesignator, CdmMetadataKey.OBJECT_DESIGNATOR.name());
153 checkNotNull(catalogName, CdmMetadataKey.CATALOG_NAME.name());
154 checkNotNull(objectName, CdmMetadataKey.OBJECT_NAME.name());
155 checkNotNull(internationalDesignator, CdmMetadataKey.INTERNATIONAL_DESIGNATOR.name());
156 checkNotNull(ephemName, CdmMetadataKey.EPHEMERIS_NAME.name());
157 checkNotNull(covarianceMethod, CdmMetadataKey.COVARIANCE_METHOD.name());
158 checkNotNull(maneuverable, CdmMetadataKey.MANEUVERABLE.name());
159 checkNotNull(refFrame, CdmMetadataKey.REF_FRAME.name());
160 }
161
162 /**
163 * Get the relative metadata following header, they are the common metadata for the CDM.
164 * @return relativeMetadata relative metadata
165 */
166 public CdmRelativeMetadata getRelativeMetadata() {
167 return relativeMetadata;
168 }
169
170 /**
171 * Set the relative metadata following header, they are the common metadata for the CDM.
172 * @param relativeMetadata relative metadata
173 */
174 public void setRelativeMetadata(final CdmRelativeMetadata relativeMetadata) {
175 this.relativeMetadata = relativeMetadata;
176 }
177
178 /**
179 * Get the object name for which metadata are given.
180 * @return the object name
181 */
182 public String getObject() {
183 return object;
184 }
185
186 /**
187 * Set the object name for which metadata are given.
188 * @param object = object 1 or 2 to be set
189 */
190 public void setObject(final String object) {
191 this.setTimeSystem(TimeSystem.UTC);
192 refuseFurtherComments();
193 this.object = object;
194 }
195
196 /**
197 * Get the object satellite catalog designator for which metadata are given.
198 * @return the satellite catalog designator for the object
199 */
200 public String getObjectDesignator() {
201 return objectDesignator;
202 }
203
204 /**
205 * Set the satellite designator for the object for which metadata are given.
206 * @param objectDesignator for the spacecraft to be set
207 */
208 public void setObjectDesignator(final String objectDesignator) {
209 refuseFurtherComments();
210 this.objectDesignator = objectDesignator;
211 }
212
213 /**
214 * Get the satellite catalog used for the object.
215 * @return the catalog name
216 */
217 public String getCatalogName() {
218 return catalogName;
219 }
220
221 /**
222 * Set the satellite catalog name used for object.
223 * @param catalogName for the spacecraft to be set
224 */
225 public void setCatalogName(final String catalogName) {
226 refuseFurtherComments();
227 this.catalogName = catalogName;
228 }
229
230 /**
231 * Get the spacecraft name for the object.
232 * @return the spacecraft name
233 */
234 public String getObjectName() {
235 return objectName;
236 }
237
238 /**
239 * Set the spacecraft name used for object.
240 * @param objectName for the spacecraft to be set
241 */
242 public void setObjectName(final String objectName) {
243 refuseFurtherComments();
244 this.objectName = objectName;
245 }
246
247 /**
248 * Get the international designator for the object.
249 * @return the international designator
250 */
251 public String getInternationalDes() {
252 return internationalDesignator;
253 }
254
255 /**
256 * Set the international designator used for object.
257 * @param internationalDes for the object to be set
258 */
259 public void setInternationalDes(final String internationalDes) {
260 refuseFurtherComments();
261 this.internationalDesignator = internationalDes;
262 }
263
264 /**
265 * Get the type of object.
266 * @return the object type
267 */
268 public ObjectType getObjectType() {
269 return objectType;
270 }
271
272 /**
273 * Set the type of object.
274 * @param objectType type of object
275 */
276 public void setObjectType(final ObjectType objectType) {
277 refuseFurtherComments();
278 this.objectType = objectType;
279 }
280
281 /**
282 * Get the contact position of the owner / operator of the object.
283 * @return the contact position
284 */
285 public String getOperatorContactPosition() {
286 return operatorContact;
287 }
288
289 /**
290 * Set the contact position for the object owner / operator.
291 * @param opContact for the object to be set
292 */
293 public void setOperatorContactPosition(final String opContact) {
294 refuseFurtherComments();
295 this.operatorContact = opContact;
296 }
297
298 /**
299 * Get the contact organisation of the object.
300 * @return the contact organisation
301 */
302 public String getOperatorOrganization() {
303 return operatorOrganization;
304 }
305
306 /**
307 * Set the contact organisation of the object.
308 * @param operatorOrganization contact organisation for the object to be set
309 */
310 public void setOperatorOrganization(final String operatorOrganization) {
311 refuseFurtherComments();
312 this.operatorOrganization = operatorOrganization;
313 }
314
315 /**
316 * Get the contact phone of the operator of the object.
317 * @return the operator phone
318 */
319 public String getOperatorPhone() {
320 return operatorPhone;
321 }
322
323 /**
324 * Set the operator phone of the object.
325 * @param operatorPhone contact phone for the object to be set
326 */
327 public void setOperatorPhone(final String operatorPhone) {
328 refuseFurtherComments();
329 this.operatorPhone = operatorPhone;
330 }
331
332 /**
333 * Get the email of the operator of the object.
334 * @return the operator email
335 */
336 public String getOperatorEmail() {
337 return operatorEmail;
338 }
339
340 /**
341 * Set the object operator email.
342 * @param operatorEmail operator email for the object to be set
343 */
344 public void setOperatorEmail(final String operatorEmail) {
345 refuseFurtherComments();
346 this.operatorEmail = operatorEmail;
347 }
348
349 /**
350 * Get the unique name of the external ephemeris used for OD.
351 * @return the name of ephemeris used
352 */
353 public String getEphemName() {
354 return ephemName;
355 }
356
357 /**
358 * Set the name of external ephemeris used for OD.
359 * @param ephemName me of external ephemeris used
360 */
361 public void setEphemName(final String ephemName) {
362 refuseFurtherComments();
363 this.ephemName = ephemName;
364 }
365
366 /**
367 * Get the method name used to calculate covariance during OD.
368 * @return the name of covariance calculation method
369 */
370 public CovarianceMethod getCovarianceMethod() {
371 return covarianceMethod;
372 }
373
374 /**
375 * Set the method name used to calculate covariance during OD.
376 * @param covarianceMethod method name for covariance calculation
377 */
378 public void setCovarianceMethod(final CovarianceMethod covarianceMethod) {
379 refuseFurtherComments();
380 this.covarianceMethod = covarianceMethod;
381 }
382
383 /**
384 * Get the ability of object to maneuver or not.
385 * @return the ability to maneuver
386 */
387 public Maneuvrable getManeuverable() {
388 return maneuverable;
389 }
390
391 /**
392 * Set the object maneuver ability.
393 * @param maneuverable ability to maneuver
394 */
395 public void setManeuverable(final Maneuvrable maneuverable) {
396 refuseFurtherComments();
397 this.maneuverable = maneuverable;
398 }
399
400 /**
401 * Get the central body for object 1 and 2.
402 * @return the name of the central body
403 */
404 public BodyFacade getOrbitCenter() {
405 return orbitCenter;
406 }
407
408 /**
409 * Set the central body name for object 1 and 2.
410 * @param orbitCenter name of the central body
411 */
412 public void setOrbitCenter(final BodyFacade orbitCenter) {
413 refuseFurtherComments();
414 this.orbitCenter = orbitCenter;
415 }
416
417 /**
418 * Get the reference frame in which data are given: used for state vector and
419 * Keplerian elements data (and for the covariance reference frame if none is given).
420 *
421 * @return the reference frame
422 */
423 public Frame getFrame() {
424 // CDM format does not allow specifying frame epoch
425 return getFrameMapper().buildCcsdsFrame(getOrbitCenter(), getRefFrame(), null);
426 }
427
428 /**
429 * Get the value of {@code REF_FRAME} as an Orekit {@link Frame}. The {@code
430 * ORBIT_CENTER} key word has not been applied yet, so the returned frame may not
431 * correspond to the reference frame of the data in the file.
432 * @return the reference frame
433 */
434 public FrameFacade getRefFrame() {
435 return refFrame;
436 }
437
438 /**
439 * Set the name of the reference frame in which the state vector data are given.
440 * @param refFrame reference frame
441 */
442 public void setRefFrame(final FrameFacade refFrame) {
443 refuseFurtherComments();
444 this.refFrame = refFrame;
445 }
446
447 /** Get gravity model name.
448 * @return gravity model name
449 */
450 public String getGravityModel() {
451 return gravityModel;
452 }
453
454 /** Get degree of the gravity model.
455 * @return degree of the gravity model
456 */
457 public int getGravityDegree() {
458 return gravityDegree;
459 }
460
461 /** Get order of the gravity model.
462 * @return order of the gravity model
463 */
464 public int getGravityOrder() {
465 return gravityOrder;
466 }
467
468 /** Set gravity model.
469 * @param name name of the model
470 * @param degree degree of the model
471 * @param order order of the model
472 */
473 public void setGravityModel(final String name, final int degree, final int order) {
474 refuseFurtherComments();
475 this.gravityModel = name;
476 this.gravityDegree = degree;
477 this.gravityOrder = order;
478 }
479
480 /** Get name of atmospheric model.
481 * @return name of atmospheric model
482 */
483 public String getAtmosphericModel() {
484 return atmosphericModel;
485 }
486
487 /** Set name of atmospheric model.
488 * @param atmosphericModel name of atmospheric model
489 */
490 public void setAtmosphericModel(final String atmosphericModel) {
491 refuseFurtherComments();
492 this.atmosphericModel = atmosphericModel;
493 }
494
495 /** Get n-body perturbation bodies.
496 * @return n-body perturbation bodies
497 */
498 public List<BodyFacade> getNBodyPerturbations() {
499 return nBodyPerturbations;
500 }
501
502 /** Set n-body perturbation bodies.
503 * @param nBody n-body perturbation bodies
504 */
505 public void setNBodyPerturbations(final List<BodyFacade> nBody) {
506 refuseFurtherComments();
507 this.nBodyPerturbations = nBody;
508 }
509
510 /**
511 * Get Enum YesNoUnknown that indicates if Solar Radiation Pressure is taken into account or not.
512 * @return isSolarRadPressure YesNoUnknown
513 */
514 public YesNoUnknown getSolarRadiationPressure() {
515 return isSolarRadPressure;
516 }
517
518 /**
519 * Set Enum that indicates if Solar Radiation Pressure is taken into account or not.
520 * @param isSolRadPressure YesNoUnknown
521 */
522 public void setSolarRadiationPressure(final YesNoUnknown isSolRadPressure) {
523 refuseFurtherComments();
524 this.isSolarRadPressure = isSolRadPressure;
525 }
526
527 /**
528 * Get Enum YesNoUnknown that indicates if Earth and ocean tides are taken into account or not.
529 * @return isEarthTides YesNoUnknown
530 */
531 public YesNoUnknown getEarthTides() {
532 return isEarthTides;
533 }
534
535 /**
536 * Set Enum YesNoUnknown that indicates if Earth and ocean tides are taken into account or not.
537 * @param EarthTides YesNoUnknown
538 */
539 public void setEarthTides(final YesNoUnknown EarthTides) {
540 refuseFurtherComments();
541 this.isEarthTides = EarthTides;
542 }
543
544 /**
545 * Get Enum YesNoUnknown that indicates if intrack thrust modeling was into account or not.
546 * @return isEarthTides YesNoUnknown
547 */
548 public YesNoUnknown getIntrackThrust() {
549 return isIntrackThrustModeled;
550 }
551
552 /**
553 * Set boolean that indicates if intrack thrust modeling was into account or not.
554 * @param IntrackThrustModeled YesNoUnknown
555 */
556 public void setIntrackThrust(final YesNoUnknown IntrackThrustModeled) {
557 refuseFurtherComments();
558 this.isIntrackThrustModeled = IntrackThrustModeled;
559 }
560
561 /** Get the source of the covariance data.
562 * @return the covarianceSource
563 */
564 public String getCovarianceSource() {
565 return covarianceSource;
566 }
567
568 /** Set the source of the covariance data.
569 * @param covarianceSource the covarianceSource to set
570 */
571 public void setCovarianceSource(final String covarianceSource) {
572 refuseFurtherComments();
573 this.covarianceSource = covarianceSource;
574 }
575
576 /** Get the flag indicating the type of alternate covariance information provided.
577 * @return the altCovType
578 */
579 public AltCovarianceType getAltCovType() {
580 return altCovType;
581 }
582
583 /** Set the flag indicating the type of alternate covariance information provided.
584 * @param altCovType the altCovType to set
585 */
586 public void setAltCovType(final AltCovarianceType altCovType) {
587 refuseFurtherComments();
588 this.altCovType = altCovType;
589 }
590
591 /**
592 * Get the value of {@code ALT_COV_REF_FRAME} as an Orekit {@link Frame}.
593 * @return the reference frame
594 */
595 public FrameFacade getAltCovRefFrame() {
596 return altCovRefFrame;
597 }
598
599 /**
600 * Set the name of the reference frame in which the alternate covariance data are given.
601 * @param altCovRefFrame alternate covariance reference frame
602 */
603 public void setAltCovRefFrame(final FrameFacade altCovRefFrame) {
604 refuseFurtherComments();
605
606 if (getAltCovType() == null) {
607 throw new OrekitException(OrekitMessages.CCSDS_MISSING_KEYWORD, CdmMetadataKey.ALT_COV_TYPE);
608 }
609
610 if (altCovRefFrame.asFrame() == null) {
611 throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, altCovRefFrame.getName());
612 }
613
614 // Only set the frame if within the allowed options: GCRF, EME2000, ITRF
615 if ( altCovRefFrame.asCelestialBodyFrame() == CelestialBodyFrame.GCRF ||
616 altCovRefFrame.asCelestialBodyFrame() == CelestialBodyFrame.EME2000 ||
617 altCovRefFrame.asCelestialBodyFrame().name().contains("ITRF") ) {
618 this.altCovRefFrame = altCovRefFrame;
619 } else {
620 throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, altCovRefFrame.getName());
621 }
622 }
623
624 /**
625 * Get the reference frame in which the alternative covariance data is
626 * given.
627 *
628 * @return alternative covariance reference frame.
629 * @see #getAltCovType()
630 * @see #getAltCovRefFrame()
631 * @since 13.1.5
632 */
633 public Frame getAltCovFrame() {
634 // Epoch of AltCovRefFrame can't be specified.
635 return getFrameMapper().buildCcsdsFrame(getAltCovRefFrame(), null);
636 }
637
638 /** Get the unique identifier of Orbit Data Message(s) that are linked (relevant) to this Conjunction Data Message.
639 * @return the odmMsgLink
640 */
641 public String getOdmMsgLink() {
642 return odmMsgLink;
643 }
644
645 /** Set the unique identifier of Orbit Data Message(s) that are linked (relevant) to this Conjunction Data Message.
646 * @param odmMsgLink the odmMsgLink to set
647 */
648 public void setOdmMsgLink(final String odmMsgLink) {
649 refuseFurtherComments();
650 this.odmMsgLink = odmMsgLink;
651 }
652
653 /** Get the unique identifier of Attitude Data Message(s) that are linked (relevant) to this Conjunction Data Message.
654 * @return the admMsgLink
655 */
656 public String getAdmMsgLink() {
657 return admMsgLink;
658 }
659
660 /** Set the unique identifier of Attitude Data Message(s) that are linked (relevant) to this Conjunction Data Message.
661 * @param admMsgLink the admMsgLink to set
662 */
663 public void setAdmMsgLink(final String admMsgLink) {
664 refuseFurtherComments();
665 this.admMsgLink = admMsgLink;
666 }
667
668 /** Get the flag indicating whether new tracking observations are anticipated prior to the issue of the next CDM associated with the event
669 * specified by CONJUNCTION_ID.
670 * @return the obsBeforeNextMessage
671 */
672 public YesNoUnknown getObsBeforeNextMessage() {
673 return obsBeforeNextMessage;
674 }
675
676 /** Set the flag indicating whether new tracking observations are anticipated prior to the issue of the next CDM associated with the event
677 * specified by CONJUNCTION_ID.
678 * @param obsBeforeNextMessage the obsBeforeNextMessage to set
679 */
680 public void setObsBeforeNextMessage(final YesNoUnknown obsBeforeNextMessage) {
681 refuseFurtherComments();
682 this.obsBeforeNextMessage = obsBeforeNextMessage;
683 }
684 }