AEMFile.java

  1. /* Copyright 2002-2020 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;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Map.Entry;

  24. import org.hipparchus.geometry.euclidean.threed.RotationOrder;
  25. import org.orekit.errors.OrekitException;
  26. import org.orekit.errors.OrekitMessages;
  27. import org.orekit.time.AbsoluteDate;
  28. import org.orekit.time.TimeScale;
  29. import org.orekit.utils.TimeStampedAngularCoordinates;

  30. /**
  31.  * This class stocks all the information of the Attitude Ephemeris Message (AEM) File parsed
  32.  * by AEMParser. It contains the header and a list of Attitude Ephemerides Blocks each
  33.  * containing metadata and a list of attitude ephemerides data lines.
  34.  * @author Bryan Cazabonne
  35.  * @since 10.2
  36.  */
  37. public class AEMFile extends ADMFile {

  38.     /** List of ephemeris blocks. */
  39.     private List<AttitudeEphemeridesBlock> attitudeBlocks;

  40.     /**
  41.      * AEMFile constructor.
  42.      */
  43.     public AEMFile() {
  44.         attitudeBlocks = new ArrayList<AttitudeEphemeridesBlock>();
  45.     }

  46.     /**
  47.      * Add a block to the list of ephemeris blocks.
  48.      */
  49.     public void addAttitudeBlock() {
  50.         attitudeBlocks.add(new AttitudeEphemeridesBlock());
  51.     }

  52.     /**
  53.      * Get the list of attitude ephemerides blocks as an unmodifiable list.
  54.      * @return the list of attitude ephemerides blocks
  55.      */
  56.     public List<AttitudeEphemeridesBlock> getAttitudeBlocks() {
  57.         return Collections.unmodifiableList(attitudeBlocks);
  58.     }

  59.     /**
  60.      * Check that, according to the CCSDS standard, every AEMBlock has the same time system.
  61.      */
  62.     public void checkTimeSystems() {
  63.         final CcsdsTimeScale timeSystem = getAttitudeBlocks().get(0).getMetaData().getTimeSystem();
  64.         for (final AttitudeEphemeridesBlock block : attitudeBlocks) {
  65.             if (!timeSystem.equals(block.getMetaData().getTimeSystem())) {
  66.                 throw new OrekitException(OrekitMessages.CCSDS_AEM_INCONSISTENT_TIME_SYSTEMS,
  67.                                           timeSystem, block.getMetaData().getTimeSystem());
  68.             }
  69.         }
  70.     }


  71.     /**
  72.      * Get the attitude loaded ephemeris for each satellite in the file.
  73.      * @return a map from the satellite's ID to the information about that satellite
  74.      * contained in the file.
  75.      */
  76.     public Map<String, AemSatelliteEphemeris> getSatellites() {
  77.         final Map<String, List<AttitudeEphemeridesBlock>> satellites = new HashMap<>();
  78.         for (final AttitudeEphemeridesBlock ephemeridesBlock : attitudeBlocks) {
  79.             final String id = ephemeridesBlock.getMetaData().getObjectID();
  80.             satellites.putIfAbsent(id, new ArrayList<>());
  81.             satellites.get(id).add(ephemeridesBlock);
  82.         }
  83.         final Map<String, AemSatelliteEphemeris> ret = new HashMap<>();
  84.         for (final Entry<String, List<AttitudeEphemeridesBlock>> entry : satellites.entrySet()) {
  85.             final String id = entry.getKey();
  86.             ret.put(id, new AemSatelliteEphemeris(entry.getValue()));
  87.         }
  88.         return ret;
  89.     }

  90.     /**
  91.      * The Attitude Ephemerides Blocks class contain metadata
  92.      * and the list of attitude data lines.
  93.      */
  94.     public class AttitudeEphemeridesBlock {

  95.         /** Meta-data for the block. */
  96.         private ADMMetaData metaData;

  97.         /** The reference frame A specifier, as it appeared in the file. */
  98.         private String refFrameAString;

  99.         /** The reference frame B specifier, as it appeared in the file. */
  100.         private String refFrameBString;

  101.         /** Rotation direction of the attitude. */
  102.         private String attitudeDir;

  103.         /** Start of total time span covered by attitude data. */
  104.         private AbsoluteDate startTime;

  105.         /** End of total time span covered by attitude data. */
  106.         private AbsoluteDate stopTime;

  107.         /** Start of useable time span covered by attitude data. */
  108.         private AbsoluteDate useableStartTime;

  109.         /** End of useable time span covered by attitude data. */
  110.         private AbsoluteDate useableStopTime;

  111.         /** The format of the data lines in the message. */
  112.         private String attitudeType;

  113.         /** The placement of the scalar portion of the quaternion (QC) in the attitude data. */
  114.         private boolean isFirst;

  115.         /**
  116.          * The rotation sequence of the Euler angles.
  117.          * (e.g., 312, where X=1, Y=2, Z=3)
  118.          */
  119.         private String eulerRotSeq;

  120.         /** The rate frame specifier, as it appeared in the file. */
  121.         private String rateFrameString;

  122.         /** The interpolation method to be used. */
  123.         private String interpolationMethod;

  124.         /** The interpolation degree. */
  125.         private int interpolationDegree;

  126.         /** The rotation order. */
  127.         private RotationOrder rotationOrder;

  128.         /** List of data lines. */
  129.         private List<TimeStampedAngularCoordinates> attitudeDataLines;

  130.         /** Data Lines comments. The list contains a string for each line of comment. */
  131.         private List<String> attitudeDataLinesComment;

  132.         /**
  133.          * Constructor.
  134.          */
  135.         public AttitudeEphemeridesBlock() {
  136.             attitudeDataLines = new ArrayList<>();
  137.             metaData          = new ADMMetaData(AEMFile.this);
  138.         }

  139.         /**
  140.          * Get the list of attitude data lines.
  141.          * @return a list of data
  142.          */
  143.         public List<TimeStampedAngularCoordinates> getAttitudeDataLines() {
  144.             return attitudeDataLines;
  145.         }

  146.         /**
  147.          * Get an unmodifiable list of attitude data lines.
  148.          * @return a list of attitude data
  149.          */
  150.         public List<TimeStampedAngularCoordinates> getAngularCoordinates() {
  151.             return Collections.unmodifiableList(this.attitudeDataLines);
  152.         }

  153.         /**
  154.          * Get the meta-data for the block.
  155.          * @return meta-data for the block
  156.          */
  157.         public ADMMetaData getMetaData() {
  158.             return metaData;
  159.         }

  160.         /**
  161.          * Get the name of the center of the coordinate system the ephemeris is provided in.
  162.          * This may be a natural origin, such as the center of the Earth, another satellite, etc.
  163.          * @return the name of the frame center
  164.          */
  165.         public String getFrameCenterString() {
  166.             return this.getMetaData().getCenterName();
  167.         }


  168.         /**
  169.          * Get the reference frame A specifier as it appeared in the file.
  170.          * @return the frame name as it appeared in the file (A).
  171.          */
  172.         public String getRefFrameAString() {
  173.             return refFrameAString;
  174.         }

  175.         /**
  176.          * Set the reference frame A name.
  177.          * @param frame specifier as it appeared in the file.
  178.          */
  179.         public void setRefFrameAString(final String frame) {
  180.             this.refFrameAString = frame;
  181.         }

  182.         /**
  183.          * Get the reference frame B specifier as it appeared in the file.
  184.          * @return the frame name as it appeared in the file (B).
  185.          */
  186.         public String getRefFrameBString() {
  187.             return this.refFrameBString;
  188.         }

  189.         /**
  190.          * Set the reference frame B name.
  191.          * @param frame specifier as it appeared in the file.
  192.          */
  193.         public void setRefFrameBString(final String frame) {
  194.             this.refFrameBString = frame;
  195.         }

  196.         /**
  197.          * Get the rate frame specifier as it appeared in the file.
  198.          * @return the rate frame name.
  199.          */
  200.         public String getRateFrameString() {
  201.             return rateFrameString;
  202.         }

  203.         /**
  204.          * Set the rate frame name.
  205.          * @param frame specifier as it appeared in the file.
  206.          */
  207.         public void setRateFrameString(final String frame) {
  208.             this.rateFrameString = frame;
  209.         }

  210.         /**
  211.          * Get the rotation direction of the attitude.
  212.          * @return the rotation direction of the attitude
  213.          */
  214.         public String getAttitudeDirection() {
  215.             return attitudeDir;
  216.         }

  217.         /**
  218.          * Set the rotation direction of the attitude.
  219.          * @param direction rotation direction to be set
  220.          */
  221.         public void setAttitudeDirection(final String direction) {
  222.             this.attitudeDir = direction;
  223.         }

  224.         /**
  225.          * Get the format of the data lines in the message.
  226.          * @return the format of the data lines in the message
  227.          */
  228.         public String getAttitudeType() {
  229.             return attitudeType;
  230.         }

  231.         /**
  232.          * Set the format of the data lines in the message.
  233.          * @param type format to be set
  234.          */
  235.         public void setAttitudeType(final String type) {
  236.             this.attitudeType = type;
  237.         }

  238.         /**
  239.          * Get the flag for the placement of the quaternion QC in the attitude data.
  240.          * @return true if QC is the first element in the attitude data
  241.          */
  242.         public boolean isFirst() {
  243.             return isFirst;
  244.         }

  245.         /**
  246.          * Set the flag for the placement of the quaternion QC in the attitude data.
  247.          * @param isFirst true if QC is the first element in the attitude data
  248.          */
  249.         public void setIsFirst(final boolean isFirst) {
  250.             this.isFirst = isFirst;
  251.         }

  252.         /**
  253.          * Get the rotation sequence of the Euler angles (e.g., 312, where X=1, Y=2, Z=3).
  254.          * @return the rotation sequence of the Euler angles
  255.          */
  256.         public String getEulerRotSeq() {
  257.             return eulerRotSeq;
  258.         }

  259.         /**
  260.          * Set the rotation sequence of the Euler angles (e.g., 312, where X=1, Y=2, Z=3).
  261.          * @param eulerRotSeq rotation sequence to be set
  262.          */
  263.         public void setEulerRotSeq(final String eulerRotSeq) {
  264.             this.eulerRotSeq = eulerRotSeq;
  265.         }

  266.         /**
  267.          * Get the time scale for this data segment.
  268.          * @return the time scale identifier, as specified in the file, or
  269.          * {@code null} if the data file does not specify a time scale.
  270.          */
  271.         public String getTimeScaleString() {
  272.             return metaData.getTimeSystem().toString();
  273.         }

  274.         /**
  275.          * Get the time scale for this data segment.
  276.          * @return the time scale for this data. Never {@code null}.
  277.          */
  278.         public TimeScale getTimeScale() {
  279.             return metaData.getTimeScale();
  280.         }

  281.         /**
  282.          * Get start of total time span covered by attitude data.
  283.          * @return the start time
  284.          */
  285.         public AbsoluteDate getStartTime() {
  286.             return startTime;
  287.         }

  288.         /**
  289.          * Set start of total time span covered by attitude data.
  290.          * @param startTime the time to be set
  291.          */
  292.         public void setStartTime(final AbsoluteDate startTime) {
  293.             this.startTime = startTime;
  294.         }

  295.         /**
  296.          * Get end of total time span covered by attitude data.
  297.          * @return the stop time
  298.          */
  299.         public AbsoluteDate getStopTime() {
  300.             return stopTime;
  301.         }

  302.         /**
  303.          * Set end of total time span covered by attitude data.
  304.          * @param stopTime the time to be set
  305.          */
  306.         public void setStopTime(final AbsoluteDate stopTime) {
  307.             this.stopTime = stopTime;
  308.         }

  309.         /**
  310.          * Get start of useable time span covered by attitude data.
  311.          * @return the useable start time
  312.          */
  313.         public AbsoluteDate getUseableStartTime() {
  314.             return useableStartTime;
  315.         }

  316.         /**
  317.          * Set start of useable time span covered by attitude data.
  318.          * @param useableStartTime the time to be set
  319.          */
  320.         public void setUseableStartTime(final AbsoluteDate useableStartTime) {
  321.             this.useableStartTime = useableStartTime;
  322.         }

  323.         /**
  324.          * Get end of useable time span covered by ephemerides data.
  325.          * @return the useable stop time
  326.          */
  327.         public AbsoluteDate getUseableStopTime() {
  328.             return useableStopTime;
  329.         }

  330.         /**
  331.          * Set end of useable time span covered by ephemerides data.
  332.          * @param useableStopTime the time to be set
  333.          */
  334.         public void setUseableStopTime(final AbsoluteDate useableStopTime) {
  335.             this.useableStopTime = useableStopTime;
  336.         }

  337.         /**
  338.          * Get the start date of this attitude data segment.
  339.          * @return attitude data segment start date.
  340.          */
  341.         public AbsoluteDate getStart() {
  342.             // usable start time overrides start time if it is set
  343.             final AbsoluteDate start = this.getUseableStartTime();
  344.             if (start != null) {
  345.                 return start;
  346.             } else {
  347.                 return this.getStartTime();
  348.             }
  349.         }

  350.         /**
  351.          * Get the end date of this attitude data segment.
  352.          * @return attitude data segment end date.
  353.          */
  354.         public AbsoluteDate getStop() {
  355.             // useable stop time overrides stop time if it is set
  356.             final AbsoluteDate stop = this.getUseableStopTime();
  357.             if (stop != null) {
  358.                 return stop;
  359.             } else {
  360.                 return this.getStopTime();
  361.             }
  362.         }

  363.         /**
  364.          * Get the interpolation method to be used.
  365.          * @return the interpolation method
  366.          */
  367.         public String getInterpolationMethod() {
  368.             return interpolationMethod;
  369.         }

  370.         /**
  371.          * Set the interpolation method to be used.
  372.          * @param interpolationMethod the interpolation method to be set
  373.          */
  374.         public void setInterpolationMethod(final String interpolationMethod) {
  375.             this.interpolationMethod = interpolationMethod;
  376.         }

  377.         /**
  378.          * Get the interpolation degree.
  379.          * @return the interpolation degree
  380.          */
  381.         public int getInterpolationDegree() {
  382.             return interpolationDegree;
  383.         }

  384.         /**
  385.          * Set the interpolation degree.
  386.          * @param interpolationDegree the interpolation degree to be set
  387.          */
  388.         public void setInterpolationDegree(final int interpolationDegree) {
  389.             this.interpolationDegree = interpolationDegree;
  390.         }

  391.         /** Get the attitude data lines comment.
  392.          * @return the comment
  393.          */
  394.         public List<String> getAttitudeDataLinesComment() {
  395.             return attitudeDataLinesComment;
  396.         }

  397.         /** Set the attitude data lines comment.
  398.          * @param ephemeridesDataLinesComment the comment to be set
  399.          */
  400.         public void setAttitudeDataLinesComment(final List<String> ephemeridesDataLinesComment) {
  401.             this.attitudeDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment);
  402.         }

  403.         /**
  404.          * Get the rotation order for Euler angles.
  405.          * @return rotation order
  406.          */
  407.         public RotationOrder getRotationOrder() {
  408.             return rotationOrder;
  409.         }

  410.         /**
  411.          * Set the rotation order for Euler angles.
  412.          * @param order the rotation order to be set
  413.          */
  414.         public void setRotationOrder(final RotationOrder order) {
  415.             this.rotationOrder = order;
  416.         }

  417.     }

  418.     /** AEM ephemeris blocks for a single satellite. */
  419.     public static class AemSatelliteEphemeris {

  420.         /** The attitude ephemeris data for the satellite. */
  421.         private final List<AttitudeEphemeridesBlock> blocks;

  422.         /**
  423.          * Create a container for the set of ephemeris blocks in the file that pertain to
  424.          * a single satellite.
  425.          * @param blocks containing ephemeris data for the satellite.
  426.          */
  427.         public AemSatelliteEphemeris(final List<AttitudeEphemeridesBlock> blocks) {
  428.             this.blocks = blocks;
  429.         }

  430.         /**
  431.          * Get the segments of the attitude ephemeris.
  432.          * <p> Ephemeris segments are typically used to split an attitude ephemeris around
  433.          * discontinuous events, such as maneuvers.
  434.          * @return the segments contained in the attitude ephemeris file for this satellite.
  435.          */
  436.         public List<AttitudeEphemeridesBlock> getSegments() {
  437.             return Collections.unmodifiableList(blocks);
  438.         }

  439.         /**
  440.          * Get the start date of the attitude ephemeris.
  441.          * @return attitude ephemeris start date.
  442.          */
  443.         public AbsoluteDate getStart() {
  444.             return blocks.get(0).getStart();
  445.         }

  446.         /**
  447.          * Get the end date of the attitude ephemeris.
  448.          * @return attitude ephemeris end date.
  449.          */
  450.         public AbsoluteDate getStop() {
  451.             return blocks.get(blocks.size() - 1).getStop();
  452.         }

  453.     }

  454. }