OrekitEphemerisFile.java

  1. /* Copyright 2016 Applied Defense Solutions (ADS)
  2.  * Licensed to CS Systèmes d'Information (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.  * ADS 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.general;

  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.orekit.bodies.CelestialBody;
  24. import org.orekit.bodies.CelestialBodyFactory;
  25. import org.orekit.errors.OrekitIllegalArgumentException;
  26. import org.orekit.errors.OrekitMessages;
  27. import org.orekit.frames.Frame;
  28. import org.orekit.propagation.SpacecraftState;
  29. import org.orekit.time.AbsoluteDate;
  30. import org.orekit.time.TimeScale;
  31. import org.orekit.time.TimeScalesFactory;
  32. import org.orekit.utils.CartesianDerivativesFilter;
  33. import org.orekit.utils.TimeStampedPVCoordinates;

  34. /**
  35.  * A class for encapsulating Orekit propagators within an {@link EphemerisFile}
  36.  * complaint object that makes for easy serialization to external ephemeris
  37.  * formats like OEM.
  38.  *
  39.  * @author Hank Grabowski
  40.  * @since 9.0
  41.  *
  42.  */
  43. public class OrekitEphemerisFile implements EphemerisFile {

  44.     /** Hashmap of satellite ephemeris. **/
  45.     private final Map<String, OrekitSatelliteEphemeris> satellites;

  46.     /**
  47.      * Standard default constructor.
  48.      */
  49.     public OrekitEphemerisFile() {
  50.         this.satellites = new ConcurrentHashMap<String, OrekitSatelliteEphemeris>();
  51.     }

  52.     @Override
  53.     public Map<String, OrekitSatelliteEphemeris> getSatellites() {
  54.         return Collections.unmodifiableMap(satellites);
  55.     }

  56.     /**
  57.      * Adds a new satellite to this object.
  58.      *
  59.      * @param id
  60.      *            ID to use for this satellite
  61.      * @return the new satellite object
  62.      */
  63.     public OrekitSatelliteEphemeris addSatellite(final String id) {
  64.         final OrekitSatelliteEphemeris newSat = new OrekitSatelliteEphemeris(id);
  65.         this.satellites.put(id, newSat);
  66.         return newSat;
  67.     }

  68.     /**
  69.      * Inner class of {@link OrekitEphemerisFile} that defines the
  70.      * {@link OrekitSatelliteEphemeris} corresponding object for this ephemeris type.
  71.      *
  72.      */
  73.     public static class OrekitSatelliteEphemeris implements SatelliteEphemeris {
  74.         /**
  75.          * Defines the default interpolation sample size if it is not specified
  76.          * on a segment.
  77.          **/
  78.         public static final int DEFAULT_INTERPOLATION_SIZE = 7;

  79.         /** ID of the space object encapsulated here. **/
  80.         private final String id;

  81.         /** Earlist date of this file. **/
  82.         private AbsoluteDate startDate;

  83.         /** Latest date of this file. **/
  84.         private AbsoluteDate stopDate;

  85.         /** List of segements in the file. **/
  86.         private final List<OrekitEphemerisSegment> segments;

  87.         /**
  88.          * Standard constructor for building the satellite Ephemeris object.
  89.          *
  90.          * @param id
  91.          *            the ID of the space object for this data
  92.          */
  93.         public OrekitSatelliteEphemeris(final String id) {
  94.             this.id = id;
  95.             this.segments = new ArrayList<OrekitEphemerisSegment>();
  96.         }

  97.         @Override
  98.         public String getId() {
  99.             return id;
  100.         }

  101.         @Override
  102.         public double getMu() {
  103.             if (this.segments.size() == 0) {
  104.                 return 0;
  105.             } else {
  106.                 return this.segments.get(0).getMu();
  107.             }
  108.         }

  109.         @Override
  110.         public List<? extends EphemerisSegment> getSegments() {
  111.             return Collections.unmodifiableList(this.segments);
  112.         }

  113.         @Override
  114.         public AbsoluteDate getStart() {
  115.             return this.startDate;
  116.         }

  117.         @Override
  118.         public AbsoluteDate getStop() {
  119.             // TODO Auto-generated method stub
  120.             return this.stopDate;
  121.         }

  122.         /**
  123.          * Injects pre-computed satellite states into this ephemeris file
  124.          * object, returning the generated {@link OrekitEphemerisSegment} that
  125.          * has been stored internally. Defaults the celestial body to earth and
  126.          * the interpolation size to the default.
  127.          *
  128.          * @param states
  129.          *            a list of {@link SpacecraftState} that will comprise this
  130.          *            new unit.
  131.          * @return the generated {@link OrekitEphemerisSegment}
  132.          */
  133.         public OrekitEphemerisSegment addNewSegment(final List<SpacecraftState> states) {
  134.             return this.addNewSegment(states, CelestialBodyFactory.getEarth(), DEFAULT_INTERPOLATION_SIZE);
  135.         }

  136.         /**
  137.          * Injects pre-computed satellite states into this ephemeris file
  138.          * object, returning the generated {@link OrekitEphemerisSegment} that
  139.          * has been stored internally. Defaults the Celestial Body to be Earths
  140.          *
  141.          * @param states
  142.          *            a list of {@link SpacecraftState} that will comprise this
  143.          *            new unit.
  144.          * @param interpolationSampleSize
  145.          *            the number of interpolation samples that should be used
  146.          *            when processed by another system
  147.          * @return the generated {@link OrekitEphemerisSegment}
  148.          */
  149.         public OrekitEphemerisSegment addNewSegment(final List<SpacecraftState> states,
  150.                 final int interpolationSampleSize) {
  151.             return this.addNewSegment(states, CelestialBodyFactory.getEarth(), interpolationSampleSize);
  152.         }

  153.         /**
  154.          * Injects pre-computed satellite states into this ephemeris file
  155.          * object, returning the generated {@link OrekitEphemerisSegment} that
  156.          * has been stored internally.
  157.          *
  158.          * @param states
  159.          *            a list of {@link SpacecraftState} that will comprise this
  160.          *            new unit.
  161.          * @param body
  162.          *            the celestial body the state's frames are with respect to
  163.          * @param interpolationSampleSize
  164.          *            the number of interpolation samples that should be used
  165.          *            when processed by another system
  166.          * @return the generated {@link OrekitEphemerisSegment}
  167.          */
  168.         public OrekitEphemerisSegment addNewSegment(final List<SpacecraftState> states, final CelestialBody body,
  169.                 final int interpolationSampleSize) {
  170.             final int minimumSampleSize = 2;
  171.             if (states == null || states.size() == 0) {
  172.                 throw new OrekitIllegalArgumentException(OrekitMessages.NULL_ARGUMENT, "states");
  173.             }

  174.             if (interpolationSampleSize < minimumSampleSize) {
  175.                 throw new OrekitIllegalArgumentException(OrekitMessages.NOT_ENOUGH_DATA_FOR_INTERPOLATION,
  176.                         interpolationSampleSize);
  177.             }

  178.             final AbsoluteDate start = states.get(0).getDate();
  179.             final AbsoluteDate stop = states.get(states.size() - 1).getDate();

  180.             if (this.startDate == null || start.compareTo(this.startDate) < 0) {
  181.                 this.startDate = start;
  182.             }

  183.             if (this.stopDate == null || stop.compareTo(this.stopDate) > 0) {
  184.                 this.stopDate = stop;
  185.             }

  186.             final List<TimeStampedPVCoordinates> coordinates = new ArrayList<TimeStampedPVCoordinates>();
  187.             for (SpacecraftState state : states) {
  188.                 coordinates.add(state.getPVCoordinates());
  189.             }

  190.             final Frame frame = states.get(0).getFrame();

  191.             final OrekitEphemerisSegment newSeg = new OrekitEphemerisSegment(coordinates, frame, body.getName(),
  192.                     body.getGM(), TimeScalesFactory.getUTC(), interpolationSampleSize);
  193.             this.segments.add(newSeg);

  194.             return newSeg;
  195.         }
  196.     }

  197.     public static class OrekitEphemerisSegment implements EphemerisSegment {
  198.         /** **/
  199.         private final List<TimeStampedPVCoordinates> coordinates;

  200.         /** **/
  201.         private final Frame frame;

  202.         /** **/
  203.         private final String frameCenterString;

  204.         /** **/
  205.         private final double mu;

  206.         /** **/
  207.         private final String timeScaleString;

  208.         /** **/
  209.         private final TimeScale timeScale;

  210.         /** **/
  211.         private final int samples;

  212.         /**
  213.          * constructor for OrekitEphemerisSegment.
  214.          *
  215.          * @param coordinates
  216.          *            coordinates making up the ephemeris for this segment
  217.          * @param frame
  218.          *            the frame the coordinates are in
  219.          * @param frameCenterString
  220.          *            the name of celestial body the frame is attached to
  221.          * @param mu
  222.          *            the gravitional constant used in force model evaluations
  223.          * @param timeScale
  224.          *            the time scale of these ephemeris points
  225.          * @param samples
  226.          *            the number of samples to use during interpolation
  227.          */
  228.         public OrekitEphemerisSegment(final List<TimeStampedPVCoordinates> coordinates, final Frame frame,
  229.                 final String frameCenterString, final double mu, final TimeScale timeScale, final int samples) {
  230.             super();
  231.             this.coordinates = coordinates;
  232.             this.frame = frame;
  233.             this.frameCenterString = frameCenterString;
  234.             this.mu = mu;
  235.             this.timeScale = timeScale;
  236.             this.timeScaleString = timeScale.getName();
  237.             this.samples = samples;
  238.         }

  239.         @Override
  240.         public double getMu() {
  241.             return mu;
  242.         }

  243.         @Override
  244.         public String getFrameCenterString() {
  245.             return frameCenterString;
  246.         }

  247.         @Override
  248.         public String getFrameString() {
  249.             return frame.getName();
  250.         }

  251.         @Override
  252.         public Frame getFrame() {
  253.             return frame;
  254.         }

  255.         @Override
  256.         public String getTimeScaleString() {
  257.             return timeScaleString;
  258.         }

  259.         @Override
  260.         public TimeScale getTimeScale() {
  261.             return timeScale;
  262.         }

  263.         @Override
  264.         public int getInterpolationSamples() {
  265.             return samples;
  266.         }

  267.         @Override
  268.         public CartesianDerivativesFilter getAvailableDerivatives() {
  269.             return CartesianDerivativesFilter.USE_PV;
  270.         }

  271.         @Override
  272.         public List<TimeStampedPVCoordinates> getCoordinates() {
  273.             return Collections.unmodifiableList(coordinates);
  274.         }

  275.         @Override
  276.         public AbsoluteDate getStart() {
  277.             return coordinates.get(0).getDate();
  278.         }

  279.         @Override
  280.         public AbsoluteDate getStop() {
  281.             return coordinates.get(coordinates.size() - 1).getDate();
  282.         }

  283.     }
  284. }