CPF.java

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

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.concurrent.ConcurrentHashMap;

  23. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  24. import org.orekit.attitudes.AttitudeProvider;
  25. import org.orekit.files.general.EphemerisFile;
  26. import org.orekit.frames.Frame;
  27. import org.orekit.propagation.BoundedPropagator;
  28. import org.orekit.time.AbsoluteDate;
  29. import org.orekit.time.TimeScale;
  30. import org.orekit.utils.CartesianDerivativesFilter;
  31. import org.orekit.utils.TimeStampedPVCoordinates;

  32. /**
  33.  * This class stores all the information of the Consolidated laser ranging Prediction File (CPF) parsed
  34.  * by CPFParser. It contains the header and a list of ephemeris entry.
  35.  * @author Bryan Cazabonne
  36.  * @since 10.3
  37.  */
  38. public class CPF implements EphemerisFile<CPF.CPFCoordinate, CPF.CPFEphemeris> {

  39.     /** Default satellite ID, used if header is null when initializing the ephemeris. */
  40.     public static final String DEFAULT_ID = "9999999";

  41.     /** Gravitational coefficient. */
  42.     private double mu;

  43.     /** The interpolation sample. */
  44.     private int interpolationSample;

  45.     /** Time scale of dates in the ephemeris file. */
  46.     private TimeScale timeScale;

  47.     /** Indicates if data contains velocity or not. */
  48.     private CartesianDerivativesFilter filter;

  49.     /** CPF file header. */
  50.     private CPFHeader header;

  51.     /** Map containing satellite information. */
  52.     private Map<String, CPFEphemeris> ephemeris;

  53.     /** List of comments contained in the file. */
  54.     private List<String> comments;

  55.     /**
  56.      * Constructor.
  57.      */
  58.     public CPF() {
  59.         this.mu        = Double.NaN;
  60.         this.ephemeris = new ConcurrentHashMap<>();
  61.         this.header    = new CPFHeader();
  62.         this.comments  = new ArrayList<>();
  63.     }

  64.     /** {@inheritDoc}
  65.      * First key corresponds to String value of {@link CPFHeader#getIlrsSatelliteId()}
  66.      */
  67.     @Override
  68.     public Map<String, CPFEphemeris> getSatellites() {
  69.         // Return the map
  70.         return Collections.unmodifiableMap(ephemeris);
  71.     }

  72.     /**
  73.      * Get the CPF file header.
  74.      * @return the CPF file header
  75.      */
  76.     public CPFHeader getHeader() {
  77.         return header;
  78.     }

  79.     /**
  80.      * Get the time scale used in CPF file.
  81.      * @return the time scale used to parse epochs in CPF file.
  82.      */
  83.     public TimeScale getTimeScale() {
  84.         return timeScale;
  85.     }

  86.     /**
  87.      * Get the comments contained in the file.
  88.      * @return the comments contained in the file
  89.      */
  90.     public List<String> getComments() {
  91.         return comments;
  92.     }

  93.     /**
  94.      * Adds a set of P/V coordinates to the satellite.
  95.      * @param id satellite ILRS identifier
  96.      * @param coord set of coordinates
  97.      * @since 11.0.1
  98.      */
  99.     public void addSatelliteCoordinates(final String id, final List<CPFCoordinate> coord) {
  100.         createIfNeeded(id);
  101.         ephemeris.get(id).coordinates.addAll(coord);
  102.     }

  103.     /**
  104.      * Add a new P/V coordinates to the satellite.
  105.      * @param id satellite ILRS identifier
  106.      * @param coord the P/V coordinate of the satellite
  107.      * @since 11.0.1
  108.      */
  109.     public void addSatelliteCoordinate(final String id, final CPFCoordinate coord) {
  110.         createIfNeeded(id);
  111.         ephemeris.get(id).coordinates.add(coord);
  112.     }

  113.     /**
  114.      * Add the velocity to the last CPF coordinate entry.
  115.      * @param id satellite ILRS identifier
  116.      * @param velocity the velocity vector of the satellite
  117.      * @since 11.2
  118.      */
  119.     public void addSatelliteVelocityToCPFCoordinate(final String id, final Vector3D velocity) {
  120.         // Get the last coordinate entry, which contains the position vector
  121.         final CPFCoordinate lastCoordinate = ephemeris.get(id).coordinates.get(ephemeris.get(id).coordinates.size() - 1);

  122.         // Create a new CPFCoordinate object with both position and velocity information
  123.         final CPFCoordinate CPFCoordUpdated = new CPFCoordinate(lastCoordinate.getDate(),
  124.                 lastCoordinate.getPosition(),
  125.                 velocity,
  126.                 lastCoordinate.getLeap());

  127.         // Patch the last record
  128.         ephemeris.get(id).coordinates.set(ephemeris.get(id).coordinates.size() - 1, CPFCoordUpdated);
  129.     }

  130.     /**
  131.      * Set the interpolation sample.
  132.      * @param interpolationSample interpolation sample
  133.      */
  134.     public void setInterpolationSample(final int interpolationSample) {
  135.         this.interpolationSample = interpolationSample;
  136.     }

  137.     /**
  138.      * Set the gravitational coefficient.
  139.      * @param mu the coefficient to be set
  140.      */
  141.     public void setMu(final double mu) {
  142.         this.mu = mu;
  143.     }

  144.     /**
  145.      * Set the time scale.
  146.      * @param timeScale use to parse dates in this file.
  147.      */
  148.     public void setTimeScale(final TimeScale timeScale) {
  149.         this.timeScale = timeScale;
  150.     }

  151.     /**
  152.      * Set the derivatives filter.
  153.      * @param filter that indicates which derivatives of position are available.
  154.      */
  155.     public void setFilter(final CartesianDerivativesFilter filter) {
  156.         this.filter = filter;
  157.     }

  158.     /**
  159.      * Create the satellite ephemeris corresponding to the given ID (if needed).
  160.      * @param id satellite ILRS identifier
  161.      */
  162.     private void createIfNeeded(final String id) {
  163.         if (ephemeris.get(id) == null) {
  164.             ephemeris.put(id, new CPFEphemeris(id));
  165.         }
  166.     }

  167.     /** An ephemeris entry  for a single satellite contains in a CPF file. */
  168.     public class CPFEphemeris
  169.         implements EphemerisFile.SatelliteEphemeris<CPFCoordinate, CPFEphemeris>,
  170.                    EphemerisFile.EphemerisSegment<CPFCoordinate> {

  171.         /** Satellite ID. */
  172.         private final String id;

  173.         /** Ephemeris Data. */
  174.         private final List<CPFCoordinate> coordinates;

  175.         /**
  176.          * Constructor.
  177.          * @param id satellite ID
  178.          */
  179.         public CPFEphemeris(final String id) {
  180.             this.id          = id;
  181.             this.coordinates = new ArrayList<>();
  182.         }


  183.         /** {@inheritDoc} */
  184.         @Override
  185.         public Frame getFrame() {
  186.             return header.getRefFrame();
  187.         }

  188.         /** {@inheritDoc} */
  189.         @Override
  190.         public int getInterpolationSamples() {
  191.             return interpolationSample;
  192.         }

  193.         /** {@inheritDoc} */
  194.         @Override
  195.         public CartesianDerivativesFilter getAvailableDerivatives() {
  196.             return filter;
  197.         }

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

  203.         /** {@inheritDoc} */
  204.         @Override
  205.         public String getId() {
  206.             return id == null ? DEFAULT_ID : id;
  207.         }

  208.         /** {@inheritDoc} */
  209.         @Override
  210.         public double getMu() {
  211.             return mu;
  212.         }

  213.         /** Returns a list containing only {@code this}. */
  214.         @Override
  215.         public List<CPFEphemeris> getSegments() {
  216.             return Collections.singletonList(this);
  217.         }

  218.         /** {@inheritDoc} */
  219.         @Override
  220.         public AbsoluteDate getStart() {
  221.             return coordinates.get(0).getDate();
  222.         }

  223.         /** {@inheritDoc} */
  224.         @Override
  225.         public AbsoluteDate getStop() {
  226.             return coordinates.get(coordinates.size() - 1).getDate();
  227.         }

  228.         /** {@inheritDoc} */
  229.         @Override
  230.         public BoundedPropagator getPropagator() {
  231.             return EphemerisSegment.super.getPropagator();
  232.         }

  233.         /** {@inheritDoc} */
  234.         @Override
  235.         public BoundedPropagator getPropagator(final AttitudeProvider attitudeProvider) {
  236.             return EphemerisSegment.super.getPropagator(attitudeProvider);
  237.         }

  238.         /** Get the list of Ephemerides data lines.
  239.          * @return a reference to the internal list of Ephemerides data lines
  240.          */
  241.         public List<CPFCoordinate> getEphemeridesDataLines() {
  242.             return this.coordinates;
  243.         }

  244.     }

  245.     /** A single record of position and possibility velocity in an SP3 file. */
  246.     public static class CPFCoordinate extends TimeStampedPVCoordinates {

  247.         /** Serializable UID. */
  248.         private static final long serialVersionUID = 20201016L;

  249.         /** Leap second flag. */
  250.         private final int leap;

  251.         /**
  252.          * Constructor with null velocity vector.
  253.          * @param date date of coordinates validity
  254.          * @param position position vector
  255.          * @param leap leap second flag (= 0 or the value of the new leap second)
  256.          */
  257.         public CPFCoordinate(final AbsoluteDate date,
  258.                              final Vector3D position,
  259.                              final int leap) {
  260.             this(date, position, Vector3D.ZERO, leap);
  261.         }

  262.         /**
  263.          * Constructor.
  264.          * @param date date of coordinates validity
  265.          * @param position position vector
  266.          * @param velocity velocity vector
  267.          * @param leap leap second flag (= 0 or the value of the new leap second)
  268.          */
  269.         public CPFCoordinate(final AbsoluteDate date,
  270.                              final Vector3D position,
  271.                              final Vector3D velocity,
  272.                              final int leap) {
  273.             super(date, position, velocity);
  274.             this.leap = leap;
  275.         }

  276.         /**
  277.          * Get the leap second flag (= 0 or the value of the new leap second).
  278.          * @return the leap second flag
  279.          */
  280.         public int getLeap() {
  281.             return leap;
  282.         }

  283.     }

  284. }