CelestialBodyFrame.java
- /* Copyright 2002-2024 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.files.ccsds.definitions;
- import java.util.regex.Pattern;
- import org.orekit.bodies.CelestialBodyFactory;
- import org.orekit.data.DataContext;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitInternalError;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.frames.Frame;
- import org.orekit.frames.ITRFVersion;
- import org.orekit.frames.VersionedITRF;
- import org.orekit.utils.IERSConventions;
- /** Frames used in CCSDS Orbit Data Messages.
- * @author Steven Ports
- * @since 6.1
- */
- public enum CelestialBodyFrame {
- /** Earth Mean Equator and Equinox of J2000. */
- EME2000 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return dataContext.getFrames().getEME2000();
- }
- },
- /** Earth Mean Equator and Equinox of J2000. */
- J2000 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return dataContext.getFrames().getEME2000();
- }
- },
- /** Geocentric Celestial Reference Frame. */
- GCRF {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return dataContext.getFrames().getGCRF();
- }
- },
- /** Greenwich Rotating Coordinates. */
- GRC {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRFEquinox(conventions, simpleEOP);
- }
- },
- /** Greenwich True Of Date.
- * @since 11.0
- */
- GTOD {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getGTOD(conventions, simpleEOP);
- }
- },
- /** International Celestial Reference Frame. */
- ICRF {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return dataContext.getFrames().getICRF();
- }
- },
- /** Latest International Terrestrial Reference Frame. */
- ITRF {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return ITRF2020.getFrame(conventions, simpleEOP, dataContext);
- }
- },
- /** International Terrestrial Reference Frame 2020. */
- ITRF2020 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_2020, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 2014. */
- ITRF2014 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_2014, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 2008. */
- ITRF2008 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_2008, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 2005. */
- ITRF2005 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_2005, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 2000. */
- ITRF2000 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_2000, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1997. */
- ITRF1997 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1997, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1996. */
- ITRF1996 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1996, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1994. */
- ITRF1994 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1994, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1993. */
- ITRF1993 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1993, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1992. */
- ITRF1992 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1992, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1991. */
- ITRF1991 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1991, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1990. */
- ITRF1990 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1990, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1989. */
- ITRF1989 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1989, conventions, simpleEOP);
- }
- },
- /** International Terrestrial Reference Frame 1988. */
- ITRF1988 {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getITRF(ITRFVersion.ITRF_1988, conventions, simpleEOP);
- }
- },
- /** Mars Centered Inertial. */
- MCI {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return dataContext.getCelestialBodies().getMars().getInertiallyOrientedFrame();
- }
- },
- /** True of Date, Rotating. */
- TDR {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getGTOD(conventions, simpleEOP);
- }
- },
- /**
- * True Equator Mean Equinox.
- * TEME may be used only for OMMs based on NORAD
- * Two Line Element sets, and in no other circumstances.
- */
- TEME {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- return dataContext.getFrames().getTEME();
- }
- },
- /** True of Date. */
- TOD {
- /** {@inheritDoc} */
- @Override
- public Frame getFrame(final IERSConventions conventions,
- final boolean simpleEOP,
- final DataContext dataContext) {
- if (conventions == null) {
- throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS);
- }
- return dataContext.getFrames().getTOD(conventions, simpleEOP);
- }
- };
- /** Pattern for dash. */
- private static final Pattern DASH = Pattern.compile("-");
- /** Suffix of the name of the inertial frame attached to a planet. */
- private static final String INERTIAL_FRAME_SUFFIX = "/inertial";
- /** Substring common to all ITRF frames. */
- private static final String ITRF_SUBSTRING = "ITRF";
- /**
- * Get the frame corresponding to the CCSDS constant.
- * @param conventions IERS conventions to use
- * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
- * @param dataContext to use when creating the frame.
- * @return frame corresponding to the CCSDS constant
- * @since 10.1
- */
- public abstract Frame getFrame(IERSConventions conventions, boolean simpleEOP, DataContext dataContext);
- /**
- * Get the name of celestial body frame.
- * @return the name of celestial body frame
- * @since 11.1
- */
- public String getName() {
- return name();
- }
- /** Parse a CCSDS frame.
- * @param frameName name of the frame, as the value of a CCSDS key=value line
- * @return CCSDS frame corresponding to the name
- */
- public static CelestialBodyFrame parse(final String frameName) {
- String canonicalized = DASH.matcher(frameName).replaceAll("");
- if (canonicalized.startsWith(ITRF_SUBSTRING) && canonicalized.length() > 4) {
- final int year = Integer.parseInt(canonicalized.substring(4));
- if (year > 87 && year < 100) {
- // convert two-digits specifications like ITRF97 into ITRF1997
- canonicalized = ITRF_SUBSTRING + (year + 1900);
- }
- }
- return CelestialBodyFrame.valueOf(canonicalized);
- }
- /**
- * Map an Orekit frame to a CCSDS frame.
- *
- * <p> The goal of this method is to perform the opposite mapping of {@link
- * #getFrame(IERSConventions, boolean, DataContext)}.
- *
- * @param frame a reference frame.
- * @return the CCSDSFrame corresponding to the Orekit frame
- */
- public static CelestialBodyFrame map(final Frame frame) {
- // Try to determine the CCSDS name from Annex A by examining the Orekit name.
- final String name = frame.getName();
- try {
- // should handle J2000, GCRF, TEME, and some frames created by OEMParser.
- return CelestialBodyFrame.valueOf(name);
- } catch (IllegalArgumentException iae) {
- if (frame instanceof ModifiedFrame) {
- return ((ModifiedFrame) frame).getRefFrame();
- } else if ((CelestialBodyFactory.MARS + INERTIAL_FRAME_SUFFIX).equals(name)) {
- return MCI;
- } else if ((CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER + INERTIAL_FRAME_SUFFIX).equals(name)) {
- return ICRF;
- } else if (name.contains("GTOD")) {
- return GTOD;
- } else if (name.contains("TOD")) { // check after GTOD
- return TOD;
- } else if (name.contains("Equinox") && name.contains(ITRF_SUBSTRING)) {
- return GRC;
- } else if (frame instanceof VersionedITRF) {
- try {
- final ITRFVersion itrfVersion = ((VersionedITRF) frame).getITRFVersion();
- return CelestialBodyFrame.valueOf(itrfVersion.name().replace("_", ""));
- } catch (IllegalArgumentException iae2) {
- // this should never happen
- throw new OrekitInternalError(iae2);
- }
- } else if (name.contains("CIO") && name.contains(ITRF_SUBSTRING)) {
- return ITRF2014;
- }
- throw new OrekitException(iae, OrekitMessages.CCSDS_INVALID_FRAME, name);
- }
- }
- /**
- * Guesses names from ODM Table 5-3 and Annex A.
- *
- * <p> The goal of this method is to perform the opposite mapping of {@link
- * #getFrame(IERSConventions, boolean, DataContext)}.
- *
- * @param frame a reference frame.
- * @return the string to use in the OEM file to identify {@code frame}.
- */
- public static String guessFrame(final Frame frame) {
- try {
- return map(frame).name();
- } catch (OrekitException oe) {
- // we were unable to find a match
- return frame.getName();
- }
- }
- }