SP3Segment.java

  1. /* Copyright Luc Maisonobe
  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.sp3;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.List;

  21. import org.hipparchus.analysis.interpolation.HermiteInterpolator;
  22. import org.orekit.attitudes.AttitudeProvider;
  23. import org.orekit.attitudes.FrameAlignedProvider;
  24. import org.orekit.files.general.EphemerisFile;
  25. import org.orekit.files.general.EphemerisSegmentPropagator;
  26. import org.orekit.frames.Frame;
  27. import org.orekit.propagation.BoundedPropagator;
  28. import org.orekit.propagation.SpacecraftState;
  29. import org.orekit.time.AbsoluteDate;
  30. import org.orekit.time.ClockModel;
  31. import org.orekit.time.ClockOffset;
  32. import org.orekit.time.SampledClockModel;
  33. import org.orekit.utils.CartesianDerivativesFilter;
  34. import org.orekit.utils.SortedListTrimmer;

  35. /** One segment of an {@link SP3Ephemeris}.
  36.  * @author Thomas Neidhart
  37.  * @author Evan Ward
  38.  * @author Luc Maisonobe
  39.  * @since 12.0
  40.  */
  41. public class SP3Segment implements EphemerisFile.EphemerisSegment<SP3Coordinate> {

  42.     /** Standard gravitational parameter in m³ / s². */
  43.     private final double mu;

  44.     /** Reference frame. */
  45.     private final Frame frame;

  46.     /** Number of points to use for interpolation. */
  47.     private final int interpolationSamples;

  48.     /** Available derivatives. */
  49.     private final CartesianDerivativesFilter filter;

  50.     /** Ephemeris Data. */
  51.     private final List<SP3Coordinate> coordinates;

  52.     /** Simple constructor.
  53.      * @param mu standard gravitational parameter to use for creating
  54.      * {@link org.orekit.orbits.Orbit Orbits} from the ephemeris data.
  55.      * @param frame reference frame
  56.      * @param interpolationSamples number of points to use for interpolation
  57.      * @param filter available derivatives
  58.      */
  59.     public SP3Segment(final double mu, final Frame frame,
  60.                       final int interpolationSamples, final CartesianDerivativesFilter filter) {
  61.         this.mu                   = mu;
  62.         this.frame                = frame;
  63.         this.interpolationSamples = interpolationSamples;
  64.         this.filter               = filter;
  65.         this.coordinates          = new ArrayList<>();
  66.     }

  67.     /** Extract the clock model.
  68.      * @return extracted clock model
  69.      * @since 12.1
  70.      */
  71.     public ClockModel extractClockModel() {
  72.         final List<ClockOffset> sample = new ArrayList<>(coordinates.size());
  73.         coordinates.forEach(c -> {
  74.             final AbsoluteDate date   = c.getDate();
  75.             final double       offset = c.getClockCorrection();
  76.             final double       rate   = filter.getMaxOrder() > 0 ? c.getClockRateChange() : Double.NaN;
  77.             sample.add(new ClockOffset(date, offset, rate, Double.NaN));
  78.         });
  79.         return new SampledClockModel(sample, interpolationSamples);
  80.     }

  81.     /** {@inheritDoc} */
  82.     @Override
  83.     public double getMu() {
  84.         return mu;
  85.     }

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     public AbsoluteDate getStart() {
  89.         return coordinates.get(0).getDate();
  90.     }

  91.     /** {@inheritDoc} */
  92.     @Override
  93.     public AbsoluteDate getStop() {
  94.         return coordinates.get(coordinates.size() - 1).getDate();
  95.     }

  96.     /** {@inheritDoc} */
  97.     @Override
  98.     public Frame getFrame() {
  99.         return frame;
  100.     }

  101.     /** {@inheritDoc} */
  102.     @Override
  103.     public int getInterpolationSamples() {
  104.         return interpolationSamples;
  105.     }

  106.     /** {@inheritDoc} */
  107.     @Override
  108.     public CartesianDerivativesFilter getAvailableDerivatives() {
  109.         return filter;
  110.     }

  111.     /** {@inheritDoc} */
  112.     @Override
  113.     public List<SP3Coordinate> getCoordinates() {
  114.         return Collections.unmodifiableList(this.coordinates);
  115.     }

  116.     /** Adds a new P/V coordinate.
  117.      * @param coord the P/V coordinate of the satellite
  118.      */
  119.     public void addCoordinate(final SP3Coordinate coord) {
  120.         coordinates.add(coord);
  121.     }

  122.     /** {@inheritDoc} */
  123.     @Override
  124.     public BoundedPropagator getPropagator() {
  125.         return new PropagatorWithClock(new FrameAlignedProvider(getInertialFrame()));
  126.     }

  127.     /** {@inheritDoc} */
  128.     @Override
  129.     public BoundedPropagator getPropagator(final AttitudeProvider attitudeProvider) {
  130.         return new PropagatorWithClock(attitudeProvider);
  131.     }

  132.     /** Propagator including clock.
  133.      * @since 12.1
  134.      */
  135.     private class PropagatorWithClock extends EphemerisSegmentPropagator<SP3Coordinate> {

  136.         /** Trimmer for coordinates list. */
  137.         private final SortedListTrimmer trimmer;

  138.         /** Simple constructor.
  139.          * @param attitudeProvider attitude porovider
  140.          */
  141.         PropagatorWithClock(final AttitudeProvider attitudeProvider) {
  142.             super(SP3Segment.this, attitudeProvider);
  143.             this.trimmer = new SortedListTrimmer(getInterpolationSamples());
  144.         }

  145.         /** {@inheritDoc} */
  146.         @Override
  147.         protected SpacecraftState updateAdditionalStates(final SpacecraftState original) {

  148.             final HermiteInterpolator interpolator = new HermiteInterpolator();

  149.             // Fill interpolator with sample
  150.             trimmer.
  151.                 getNeighborsSubList(original.getDate(), coordinates).
  152.                 forEach(c -> {
  153.                     final double deltaT = c.getDate().durationFrom(original.getDate());
  154.                     if (filter.getMaxOrder() < 1) {
  155.                         // we use only clock offset
  156.                         interpolator.addSamplePoint(deltaT,
  157.                                                     new double[] { c.getClockCorrection() });
  158.                     } else {
  159.                         // we use both clock offset and clock rate
  160.                         interpolator.addSamplePoint(deltaT,
  161.                                                     new double[] { c.getClockCorrection() },
  162.                                                     new double[] { c.getClockRateChange() });
  163.                     }
  164.                 });

  165.             // perform interpolation (we get derivatives even if we used only clock offset)
  166.             final double[][] derivatives = interpolator.derivatives(0.0, 1);

  167.             // add the clock offset and its first derivative
  168.             return super.updateAdditionalStates(original).
  169.                 addAdditionalState(SP3Utils.CLOCK_ADDITIONAL_STATE, derivatives[0]).
  170.                 addAdditionalStateDerivative(SP3Utils.CLOCK_ADDITIONAL_STATE, derivatives[1]);

  171.         }

  172.     }

  173. }