TODProvider.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.frames;

  18. import java.io.Serializable;

  19. import org.hipparchus.RealFieldElement;
  20. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  21. import org.hipparchus.geometry.euclidean.threed.Rotation;
  22. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  23. import org.hipparchus.geometry.euclidean.threed.RotationOrder;
  24. import org.orekit.annotation.DefaultDataContext;
  25. import org.orekit.data.DataContext;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.errors.OrekitInternalError;
  28. import org.orekit.time.AbsoluteDate;
  29. import org.orekit.time.FieldAbsoluteDate;
  30. import org.orekit.time.TimeScalarFunction;
  31. import org.orekit.time.TimeScales;
  32. import org.orekit.time.TimeVectorFunction;
  33. import org.orekit.utils.IERSConventions;

  34. /** Provider for True of Date (ToD) frame.
  35.  * <p>This frame handles nutation effects according to selected IERS conventions.</p>
  36.  * <p>Transform is computed with reference to the {@link MODProvider Mean of Date} frame.</p>
  37.  * @author Pascal Parraud
  38.  */
  39. class TODProvider implements EOPBasedTransformProvider {

  40.     /** Serializable UID. */
  41.     private static final long serialVersionUID = 20131209L;

  42.     /** Conventions. */
  43.     private final IERSConventions conventions;

  44.     /** EOP history. */
  45.     private final EOPHistory eopHistory;

  46.     /** Function computing the mean obliquity. */
  47.     private final transient TimeScalarFunction obliquityFunction;

  48.     /** Function computing the nutation angles. */
  49.     private final transient TimeVectorFunction nutationFunction;


  50.     /**
  51.      * Simple constructor.
  52.      *  @param conventions IERS conventions to apply
  53.      * @param eopHistory  EOP history, or {@code null} if no correction should be
  54.      *                    applied.
  55.      * @param timeScales         TAI time scale.
  56.      */
  57.     TODProvider(final IERSConventions conventions,
  58.                 final EOPHistory eopHistory,
  59.                 final TimeScales timeScales) {
  60.         this.conventions       = conventions;
  61.         this.eopHistory        = eopHistory;
  62.         this.obliquityFunction = conventions.getMeanObliquityFunction(timeScales);
  63.         this.nutationFunction  =
  64.                 conventions.getNutationFunction(timeScales);
  65.     }

  66.     /**
  67.      * Private constructor.
  68.      *
  69.      * @param conventions       IERS conventions to use.
  70.      * @param eopHistory        or {@code null} if no correction should be applied.
  71.      * @param obliquityFunction to use.
  72.      * @param nutationFunction  to use.
  73.      */
  74.     private TODProvider(final IERSConventions conventions,
  75.                         final EOPHistory eopHistory,
  76.                         final TimeScalarFunction obliquityFunction,
  77.                         final TimeVectorFunction nutationFunction) {
  78.         this.conventions = conventions;
  79.         this.eopHistory = eopHistory;
  80.         this.obliquityFunction = obliquityFunction;
  81.         this.nutationFunction = nutationFunction;
  82.     }

  83.     /** {@inheritDoc} */
  84.     @Override
  85.     public EOPHistory getEOPHistory() {
  86.         return eopHistory;
  87.     }

  88.     /** {@inheritDoc} */
  89.     @Override
  90.     public TODProvider getNonInterpolatingProvider() {
  91.         return new TODProvider(conventions, eopHistory.getNonInterpolatingEOPHistory(),
  92.                 obliquityFunction, nutationFunction);
  93.     }

  94.     /** {@inheritDoc} */
  95.     @Override
  96.     public Transform getTransform(final AbsoluteDate date) {

  97.         // compute nutation angles
  98.         final double[] angles = nutationFunction.value(date);

  99.         // compute the mean obliquity of the ecliptic
  100.         final double moe = obliquityFunction.value(date);

  101.         double dpsi = angles[0];
  102.         double deps = angles[1];
  103.         if (eopHistory != null) {
  104.             // apply the corrections for the nutation parameters
  105.             final double[] correction = eopHistory.getEquinoxNutationCorrection(date);
  106.             dpsi += correction[0];
  107.             deps += correction[1];
  108.         }

  109.         // compute the true obliquity of the ecliptic
  110.         final double toe = moe + deps;

  111.         // complete nutation
  112.         final Rotation nutation = new Rotation(RotationOrder.XZX, RotationConvention.FRAME_TRANSFORM,
  113.                                                moe, -dpsi, -toe);

  114.         // set up the transform from parent MOD
  115.         return new Transform(date, nutation);

  116.     }

  117.     /** Replace the instance with a data transfer object for serialization.
  118.     /** {@inheritDoc} */
  119.     @Override
  120.     public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {

  121.         // compute nutation angles
  122.         final T[] angles = nutationFunction.value(date);

  123.         // compute the mean obliquity of the ecliptic
  124.         final T moe = obliquityFunction.value(date);

  125.         T dpsi = angles[0];
  126.         T deps = angles[1];
  127.         if (eopHistory != null) {
  128.             // apply the corrections for the nutation parameters
  129.             final T[] correction = eopHistory.getEquinoxNutationCorrection(date);
  130.             dpsi = dpsi.add(correction[0]);
  131.             deps = deps.add(correction[1]);
  132.         }

  133.         // compute the true obliquity of the ecliptic
  134.         final T toe = moe.add(deps);

  135.         // complete nutation
  136.         final FieldRotation<T> nutation = new FieldRotation<>(RotationOrder.XZX, RotationConvention.FRAME_TRANSFORM,
  137.                                                               moe, dpsi.negate(), toe.negate());

  138.         // set up the transform from parent MOD
  139.         return new FieldTransform<>(date, nutation);

  140.     }

  141.     /** Replace the instance with a data transfer object for serialization.
  142.      * <p>
  143.      * This intermediate class serializes only the frame key.
  144.      * </p>
  145.      * @return data transfer object that will be serialized
  146.      */
  147.     @DefaultDataContext
  148.     private Object writeReplace() {
  149.         return new DataTransferObject(conventions, eopHistory);
  150.     }

  151.     /** Internal class used only for serialization. */
  152.     @DefaultDataContext
  153.     private static class DataTransferObject implements Serializable {

  154.         /** Serializable UID. */
  155.         private static final long serialVersionUID = 20131209L;

  156.         /** Conventions. */
  157.         private final IERSConventions conventions;

  158.         /** EOP history. */
  159.         private final EOPHistory eopHistory;

  160.         /** Simple constructor.
  161.          * @param conventions IERS conventions to apply
  162.          * @param eopHistory EOP history
  163.          */
  164.         DataTransferObject(final IERSConventions conventions, final EOPHistory eopHistory) {
  165.             this.conventions = conventions;
  166.             this.eopHistory  = eopHistory;
  167.         }

  168.         /** Replace the deserialized data transfer object with a {@link TODProvider}.
  169.          * @return replacement {@link TODProvider}
  170.          */
  171.         private Object readResolve() {
  172.             try {
  173.                 // retrieve a managed frame
  174.                 return new TODProvider(conventions, eopHistory,
  175.                         DataContext.getDefault().getTimeScales());
  176.             } catch (OrekitException oe) {
  177.                 throw new OrekitInternalError(oe);
  178.             }
  179.         }

  180.     }

  181. }