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.files.general.AttitudeEphemerisFile;
  28. import org.orekit.frames.Frame;
  29. import org.orekit.time.AbsoluteDate;
  30. import org.orekit.time.TimeScale;
  31. import org.orekit.utils.AngularDerivativesFilter;
  32. import org.orekit.utils.TimeStampedAngularCoordinates;

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

  41.     /** List of ephemeris blocks. */
  42.     private List<AttitudeEphemeridesBlock> attitudeBlocks;

  43.     /**
  44.      * AEMFile constructor.
  45.      */
  46.     public AEMFile() {
  47.         attitudeBlocks = new ArrayList<AttitudeEphemeridesBlock>();
  48.     }

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

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

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

  74.     /** {@inheritDoc} */
  75.     @Override
  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(id, entry.getValue()));
  87.         }
  88.         return ret;
  89.     }


  90.     /** AEM ephemeris blocks for a single satellite. */
  91.     public static class AemSatelliteEphemeris implements SatelliteAttitudeEphemeris {

  92.         /** ID of the satellite. */
  93.         private final String id;

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

  96.         /**
  97.          * Create a container for the set of ephemeris blocks in the file that pertain to
  98.          * a single satellite. The satellite's ID is set to ""
  99.          * @param blocks containing ephemeris data for the satellite.
  100.          * @deprecated in 10.3, replaced by AemSatelliteEphemeris(String, List)
  101.          */
  102.         @Deprecated
  103.         public AemSatelliteEphemeris(final List<AttitudeEphemeridesBlock> blocks) {
  104.             this("", blocks);
  105.         }

  106.         /**
  107.          * Create a container for the set of ephemeris blocks in the file that pertain to
  108.          * a single satellite.
  109.          * @param id     of the satellite.
  110.          * @param blocks containing ephemeris data for the satellite.
  111.          * @since 10.3
  112.          */
  113.         public AemSatelliteEphemeris(final String id, final List<AttitudeEphemeridesBlock> blocks) {
  114.             this.id = id;
  115.             this.blocks = blocks;
  116.         }

  117.         /** {@inheritDoc} */
  118.         @Override
  119.         public String getId() {
  120.             return this.id;
  121.         }

  122.         /** {@inheritDoc} */
  123.         @Override
  124.         public List<AttitudeEphemeridesBlock> getSegments() {
  125.             return Collections.unmodifiableList(blocks);
  126.         }

  127.         /** {@inheritDoc} */
  128.         @Override
  129.         public AbsoluteDate getStart() {
  130.             return blocks.get(0).getStart();
  131.         }

  132.         /** {@inheritDoc} */
  133.         @Override
  134.         public AbsoluteDate getStop() {
  135.             return blocks.get(blocks.size() - 1).getStop();
  136.         }

  137.     }

  138.     /**
  139.      * The Attitude Ephemerides Blocks class contain metadata
  140.      * and the list of attitude data lines.
  141.      */
  142.     public class AttitudeEphemeridesBlock implements AttitudeEphemerisSegment {

  143.         /** Meta-data for the block. */
  144.         private ADMMetaData metaData;

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

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

  149.         /** The reference frame from which attitude is defined. */
  150.         private Frame refFrame;

  151.         /** Rotation direction of the attitude. */
  152.         private String attitudeDir;

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

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

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

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

  161.         /** The format of the data lines in the message. */
  162.         private String attitudeType;

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

  165.         /**
  166.          * The rotation sequence of the Euler angles.
  167.          * (e.g., 312, where X=1, Y=2, Z=3)
  168.          */
  169.         private String eulerRotSeq;

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

  172.         /** The interpolation method to be used. */
  173.         private String interpolationMethod;

  174.         /** The interpolation degree. */
  175.         private int interpolationDegree;

  176.         /** The rotation order. */
  177.         private RotationOrder rotationOrder;

  178.         /** List of data lines. */
  179.         private List<TimeStampedAngularCoordinates> attitudeDataLines;

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

  182.         /** Enumerate for selecting which derivatives to use in {@link #attitudeDataLines}. */
  183.         private AngularDerivativesFilter angularDerivativesFilter;

  184.         /**
  185.          * Constructor.
  186.          */
  187.         public AttitudeEphemeridesBlock() {
  188.             attitudeDataLines = new ArrayList<>();
  189.             metaData          = new ADMMetaData(AEMFile.this);
  190.         }

  191.         /**
  192.          * Get the list of attitude data lines.
  193.          * @return a list of data
  194.          */
  195.         public List<TimeStampedAngularCoordinates> getAttitudeDataLines() {
  196.             return attitudeDataLines;
  197.         }

  198.         /** {@inheritDoc} */
  199.         @Override
  200.         public List<TimeStampedAngularCoordinates> getAngularCoordinates() {
  201.             return Collections.unmodifiableList(this.attitudeDataLines);
  202.         }

  203.         /** {@inheritDoc} */
  204.         @Override
  205.         public AngularDerivativesFilter getAvailableDerivatives() {
  206.             return angularDerivativesFilter;
  207.         }

  208.         /**
  209.          * Update the value of {@link #angularDerivativesFilter}.
  210.          *
  211.          * @param pointAngularDerivativesFilter enumerate for selecting which derivatives to use in
  212.          *                                      attitude data.
  213.          */
  214.         void updateAngularDerivativesFilter(final AngularDerivativesFilter pointAngularDerivativesFilter) {
  215.             this.angularDerivativesFilter = pointAngularDerivativesFilter;
  216.         }

  217.         /**
  218.          * Get the meta-data for the block.
  219.          * @return meta-data for the block
  220.          */
  221.         public ADMMetaData getMetaData() {
  222.             return metaData;
  223.         }

  224.         /** {@inheritDoc} */
  225.         @Override
  226.         public String getFrameCenterString() {
  227.             return this.getMetaData().getCenterName();
  228.         }

  229.         /** {@inheritDoc} */
  230.         @Override
  231.         public String getRefFrameAString() {
  232.             return refFrameAString;
  233.         }

  234.         /**
  235.          * Set the reference frame A name.
  236.          * @param frame specifier as it appeared in the file.
  237.          */
  238.         public void setRefFrameAString(final String frame) {
  239.             this.refFrameAString = frame;
  240.         }

  241.         /** {@inheritDoc} */
  242.         @Override
  243.         public String getRefFrameBString() {
  244.             return this.refFrameBString;
  245.         }

  246.         /**
  247.          * Set the reference frame B name.
  248.          * @param frame specifier as it appeared in the file.
  249.          */
  250.         public void setRefFrameBString(final String frame) {
  251.             this.refFrameBString = frame;
  252.         }

  253.         /**
  254.          * Get the reference frame from which attitude is defined.
  255.          * @param frame reference frame
  256.          */
  257.         public void setReferenceFrame(final Frame frame) {
  258.             this.refFrame = frame;

  259.         }

  260.         /** {@inheritDoc} */
  261.         @Override
  262.         public Frame getReferenceFrame() {
  263.             return refFrame;
  264.         }

  265.         /**
  266.          * Get the rate frame specifier as it appeared in the file.
  267.          * @return the rate frame name.
  268.          */
  269.         public String getRateFrameString() {
  270.             return rateFrameString;
  271.         }

  272.         /**
  273.          * Set the rate frame name.
  274.          * @param frame specifier as it appeared in the file.
  275.          */
  276.         public void setRateFrameString(final String frame) {
  277.             this.rateFrameString = frame;
  278.         }

  279.         /** {@inheritDoc} */
  280.         @Override
  281.         public String getAttitudeDirection() {
  282.             return attitudeDir;
  283.         }

  284.         /**
  285.          * Set the rotation direction of the attitude.
  286.          * @param direction rotation direction to be set
  287.          */
  288.         public void setAttitudeDirection(final String direction) {
  289.             this.attitudeDir = direction;
  290.         }

  291.         /** {@inheritDoc} */
  292.         @Override
  293.         public String getAttitudeType() {
  294.             return attitudeType;
  295.         }

  296.         /**
  297.          * Set the format of the data lines in the message.
  298.          * @param type format to be set
  299.          */
  300.         public void setAttitudeType(final String type) {
  301.             this.attitudeType = type;
  302.         }

  303.         /** {@inheritDoc} */
  304.         @Override
  305.         public boolean isFirst() {
  306.             return isFirst;
  307.         }

  308.         /**
  309.          * Set the flag for the placement of the quaternion QC in the attitude data.
  310.          * @param isFirst true if QC is the first element in the attitude data
  311.          */
  312.         public void setIsFirst(final boolean isFirst) {
  313.             this.isFirst = isFirst;
  314.         }

  315.         /**
  316.          * Get the rotation sequence of the Euler angles (e.g., 312, where X=1, Y=2, Z=3).
  317.          * @return the rotation sequence of the Euler angles
  318.          */
  319.         public String getEulerRotSeq() {
  320.             return eulerRotSeq;
  321.         }

  322.         /**
  323.          * Set the rotation sequence of the Euler angles (e.g., 312, where X=1, Y=2, Z=3).
  324.          * @param eulerRotSeq rotation sequence to be set
  325.          */
  326.         public void setEulerRotSeq(final String eulerRotSeq) {
  327.             this.eulerRotSeq = eulerRotSeq;
  328.         }

  329.         /** {@inheritDoc} */
  330.         @Override
  331.         public String getTimeScaleString() {
  332.             return metaData.getTimeSystem().toString();
  333.         }

  334.         /** {@inheritDoc} */
  335.         @Override
  336.         public TimeScale getTimeScale() {
  337.             return metaData.getTimeScale();
  338.         }

  339.         /**
  340.          * Get start of total time span covered by attitude data.
  341.          * @return the start time
  342.          */
  343.         public AbsoluteDate getStartTime() {
  344.             return startTime;
  345.         }

  346.         /**
  347.          * Set start of total time span covered by attitude data.
  348.          * @param startTime the time to be set
  349.          */
  350.         public void setStartTime(final AbsoluteDate startTime) {
  351.             this.startTime = startTime;
  352.         }

  353.         /**
  354.          * Get end of total time span covered by attitude data.
  355.          * @return the stop time
  356.          */
  357.         public AbsoluteDate getStopTime() {
  358.             return stopTime;
  359.         }

  360.         /**
  361.          * Set end of total time span covered by attitude data.
  362.          * @param stopTime the time to be set
  363.          */
  364.         public void setStopTime(final AbsoluteDate stopTime) {
  365.             this.stopTime = stopTime;
  366.         }

  367.         /**
  368.          * Get start of useable time span covered by attitude data.
  369.          * @return the useable start time
  370.          */
  371.         public AbsoluteDate getUseableStartTime() {
  372.             return useableStartTime;
  373.         }

  374.         /**
  375.          * Set start of useable time span covered by attitude data.
  376.          * @param useableStartTime the time to be set
  377.          */
  378.         public void setUseableStartTime(final AbsoluteDate useableStartTime) {
  379.             this.useableStartTime = useableStartTime;
  380.         }

  381.         /**
  382.          * Get end of useable time span covered by ephemerides data.
  383.          * @return the useable stop time
  384.          */
  385.         public AbsoluteDate getUseableStopTime() {
  386.             return useableStopTime;
  387.         }

  388.         /**
  389.          * Set end of useable time span covered by ephemerides data.
  390.          * @param useableStopTime the time to be set
  391.          */
  392.         public void setUseableStopTime(final AbsoluteDate useableStopTime) {
  393.             this.useableStopTime = useableStopTime;
  394.         }

  395.         /** {@inheritDoc} */
  396.         @Override
  397.         public AbsoluteDate getStart() {
  398.             // usable start time overrides start time if it is set
  399.             final AbsoluteDate start = this.getUseableStartTime();
  400.             if (start != null) {
  401.                 return start;
  402.             } else {
  403.                 return this.getStartTime();
  404.             }
  405.         }

  406.         /** {@inheritDoc} */
  407.         @Override
  408.         public AbsoluteDate getStop() {
  409.             // useable stop time overrides stop time if it is set
  410.             final AbsoluteDate stop = this.getUseableStopTime();
  411.             if (stop != null) {
  412.                 return stop;
  413.             } else {
  414.                 return this.getStopTime();
  415.             }
  416.         }

  417.         /** {@inheritDoc} */
  418.         @Override
  419.         public String getInterpolationMethod() {
  420.             return interpolationMethod;
  421.         }

  422.         /**
  423.          * Set the interpolation method to be used.
  424.          * @param interpolationMethod the interpolation method to be set
  425.          */
  426.         public void setInterpolationMethod(final String interpolationMethod) {
  427.             this.interpolationMethod = interpolationMethod;
  428.         }

  429.         /**
  430.          * Get the interpolation degree.
  431.          * @return the interpolation degree
  432.          */
  433.         public int getInterpolationDegree() {
  434.             return interpolationDegree;
  435.         }

  436.         /**
  437.          * Set the interpolation degree.
  438.          * @param interpolationDegree the interpolation degree to be set
  439.          */
  440.         public void setInterpolationDegree(final int interpolationDegree) {
  441.             this.interpolationDegree = interpolationDegree;
  442.         }

  443.         /** {@inheritDoc} */
  444.         @Override
  445.         public int getInterpolationSamples() {
  446.             // From the standard it is not entirely clear how to interpret the degree.
  447.             return getInterpolationDegree() + 1;
  448.         }

  449.         /** Get the attitude data lines comment.
  450.          * @return the comment
  451.          */
  452.         public List<String> getAttitudeDataLinesComment() {
  453.             return attitudeDataLinesComment;
  454.         }

  455.         /** Set the attitude data lines comment.
  456.          * @param ephemeridesDataLinesComment the comment to be set
  457.          */
  458.         public void setAttitudeDataLinesComment(final List<String> ephemeridesDataLinesComment) {
  459.             this.attitudeDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment);
  460.         }

  461.         /** {@inheritDoc} */
  462.         @Override
  463.         public RotationOrder getRotationOrder() {
  464.             return rotationOrder;
  465.         }

  466.         /**
  467.          * Set the rotation order for Euler angles.
  468.          * @param order the rotation order to be set
  469.          */
  470.         public void setRotationOrder(final RotationOrder order) {
  471.             this.rotationOrder = order;
  472.         }

  473.     }


  474. }