EstimatedEarthFrameProvider.java

  1. /* Copyright 2002-2024 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.estimation.measurements;

  18. import java.io.Serializable;
  19. import java.util.Map;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.hipparchus.analysis.differentiation.Gradient;
  22. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  23. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  24. import org.hipparchus.geometry.euclidean.threed.Rotation;
  25. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  26. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  27. import org.hipparchus.util.FastMath;
  28. import org.orekit.errors.OrekitException;
  29. import org.orekit.errors.OrekitInternalError;
  30. import org.orekit.errors.OrekitMessages;
  31. import org.orekit.frames.FieldStaticTransform;
  32. import org.orekit.frames.FieldTransform;
  33. import org.orekit.frames.StaticTransform;
  34. import org.orekit.frames.Transform;
  35. import org.orekit.frames.TransformProvider;
  36. import org.orekit.time.AbsoluteDate;
  37. import org.orekit.time.FieldAbsoluteDate;
  38. import org.orekit.time.UT1Scale;
  39. import org.orekit.utils.IERSConventions;
  40. import org.orekit.utils.ParameterDriver;

  41. /** Class modeling an Earth frame whose Earth Orientation Parameters can be estimated.
  42.  * <p>
  43.  * This class adds parameters for an additional polar motion
  44.  * and an additional prime meridian orientation on top of an underlying regular Earth
  45.  * frame like {@link org.orekit.frames.FramesFactory#getITRF(IERSConventions, boolean) ITRF}.
  46.  * The polar motion and prime meridian orientation are applied <em>after</em> regular Earth
  47.  * orientation parameters, so the value of the estimated parameters will be correction to EOP,
  48.  * they will not be the complete EOP values by themselves. Basically, this means that for
  49.  * Earth, the following transforms are applied in order, between inertial frame and this frame:
  50.  * </p>
  51.  * <ol>
  52.  *   <li>precession/nutation, as theoretical model plus celestial pole EOP parameters</li>
  53.  *   <li>body rotation, as theoretical model plus prime meridian EOP parameters</li>
  54.  *   <li>polar motion, which is only from EOP parameters (no theoretical models)</li>
  55.  *   <li>additional body rotation, controlled by {@link #getPrimeMeridianOffsetDriver()} and {@link #getPrimeMeridianDriftDriver()}</li>
  56.  *   <li>additional polar motion, controlled by {@link #getPolarOffsetXDriver()}, {@link #getPolarDriftXDriver()},
  57.  *   {@link #getPolarOffsetYDriver()} and {@link #getPolarDriftYDriver()}</li>
  58.  * </ol>
  59.  * @author Luc Maisonobe
  60.  * @since 9.1
  61.  */
  62. public class EstimatedEarthFrameProvider implements TransformProvider {

  63.     /** Earth Angular Velocity, in rad/s, from TIRF model. */
  64.     public static final double EARTH_ANGULAR_VELOCITY = 7.292115146706979e-5;

  65.     /** Serializable UID. */
  66.     private static final long serialVersionUID = 20170922L;

  67.     /** Angular scaling factor.
  68.      * <p>
  69.      * We use a power of 2 to avoid numeric noise introduction
  70.      * in the multiplications/divisions sequences.
  71.      * </p>
  72.      */
  73.     private static final double ANGULAR_SCALE = FastMath.scalb(1.0, -22);

  74.     /** Underlying raw UT1. */
  75.     private final UT1Scale baseUT1;

  76.     /** Estimated UT1. */
  77.     private final transient UT1Scale estimatedUT1;

  78.     /** Driver for prime meridian offset. */
  79.     private final transient ParameterDriver primeMeridianOffsetDriver;

  80.     /** Driver for prime meridian drift. */
  81.     private final transient ParameterDriver primeMeridianDriftDriver;

  82.     /** Driver for pole offset along X. */
  83.     private final transient ParameterDriver polarOffsetXDriver;

  84.     /** Driver for pole drift along X. */
  85.     private final transient ParameterDriver polarDriftXDriver;

  86.     /** Driver for pole offset along Y. */
  87.     private final transient ParameterDriver polarOffsetYDriver;

  88.     /** Driver for pole drift along Y. */
  89.     private final transient ParameterDriver polarDriftYDriver;

  90.     /** Build an estimated Earth frame.
  91.      * <p>
  92.      * The initial values for the pole and prime meridian parametric linear models
  93.      * ({@link #getPrimeMeridianOffsetDriver()}, {@link #getPrimeMeridianDriftDriver()},
  94.      * {@link #getPolarOffsetXDriver()}, {@link #getPolarDriftXDriver()},
  95.      * {@link #getPolarOffsetXDriver()}, {@link #getPolarDriftXDriver()}) are set to 0.
  96.      * </p>
  97.      * @param baseUT1 underlying base UT1
  98.      * @since 9.1
  99.      */
  100.     public EstimatedEarthFrameProvider(final UT1Scale baseUT1) {

  101.         this.primeMeridianOffsetDriver = new ParameterDriver("prime-meridian-offset",
  102.                                                              0.0, ANGULAR_SCALE,
  103.                                                             -FastMath.PI, FastMath.PI);

  104.         this.primeMeridianDriftDriver = new ParameterDriver("prime-meridian-drift",
  105.                                                             0.0, ANGULAR_SCALE,
  106.                                                             Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);

  107.         this.polarOffsetXDriver = new ParameterDriver("polar-offset-X",
  108.                                                       0.0, ANGULAR_SCALE,
  109.                                                       -FastMath.PI, FastMath.PI);

  110.         this.polarDriftXDriver = new ParameterDriver("polar-drift-X",
  111.                                                      0.0, ANGULAR_SCALE,
  112.                                                      Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);

  113.         this.polarOffsetYDriver = new ParameterDriver("polar-offset-Y",
  114.                                                       0.0, ANGULAR_SCALE,
  115.                                                       -FastMath.PI, FastMath.PI);

  116.         this.polarDriftYDriver = new ParameterDriver("polar-drift-Y",
  117.                                                      0.0, ANGULAR_SCALE,
  118.                                                      Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);

  119.         this.baseUT1      = baseUT1;
  120.         this.estimatedUT1 = new EstimatedUT1Scale();

  121.     }

  122.     /** Get a driver allowing to add a prime meridian rotation.
  123.      * <p>
  124.      * The parameter is an angle in radians. In order to convert this
  125.      * value to a DUT1 in seconds, the value must be divided by
  126.      * {@link #EARTH_ANGULAR_VELOCITY} (nominal Angular Velocity of Earth).
  127.      * </p>
  128.      * @return driver for prime meridian rotation
  129.      */
  130.     public ParameterDriver getPrimeMeridianOffsetDriver() {
  131.         return primeMeridianOffsetDriver;
  132.     }

  133.     /** Get a driver allowing to add a prime meridian rotation rate.
  134.      * <p>
  135.      * The parameter is an angle rate in radians per second. In order to convert this
  136.      * value to a LOD in seconds, the value must be multiplied by -86400 and divided by
  137.      * {@link #EARTH_ANGULAR_VELOCITY} (nominal Angular Velocity of Earth).
  138.      * </p>
  139.      * @return driver for prime meridian rotation rate
  140.      */
  141.     public ParameterDriver getPrimeMeridianDriftDriver() {
  142.         return primeMeridianDriftDriver;
  143.     }

  144.     /** Get a driver allowing to add a polar offset along X.
  145.      * <p>
  146.      * The parameter is an angle in radians
  147.      * </p>
  148.      * @return driver for polar offset along X
  149.      */
  150.     public ParameterDriver getPolarOffsetXDriver() {
  151.         return polarOffsetXDriver;
  152.     }

  153.     /** Get a driver allowing to add a polar drift along X.
  154.      * <p>
  155.      * The parameter is an angle rate in radians per second
  156.      * </p>
  157.      * @return driver for polar drift along X
  158.      */
  159.     public ParameterDriver getPolarDriftXDriver() {
  160.         return polarDriftXDriver;
  161.     }

  162.     /** Get a driver allowing to add a polar offset along Y.
  163.      * <p>
  164.      * The parameter is an angle in radians
  165.      * </p>
  166.      * @return driver for polar offset along Y
  167.      */
  168.     public ParameterDriver getPolarOffsetYDriver() {
  169.         return polarOffsetYDriver;
  170.     }

  171.     /** Get a driver allowing to add a polar drift along Y.
  172.      * <p>
  173.      * The parameter is an angle rate in radians per second
  174.      * </p>
  175.      * @return driver for polar drift along Y
  176.      */
  177.     public ParameterDriver getPolarDriftYDriver() {
  178.         return polarDriftYDriver;
  179.     }

  180.     /** Get the estimated UT1 time scale.
  181.      * @return estimated UT1 time scale
  182.      */
  183.     public UT1Scale getEstimatedUT1() {
  184.         return estimatedUT1;
  185.     }

  186.     /** {@inheritDoc} */
  187.     @Override
  188.     public Transform getTransform(final AbsoluteDate date) {

  189.         // take parametric prime meridian shift into account
  190.         final double theta    = linearModel(date, primeMeridianOffsetDriver, primeMeridianDriftDriver);
  191.         final double thetaDot = primeMeridianDriftDriver.getValue();
  192.         final Transform meridianShift =
  193.                         new Transform(date,
  194.                                       new Rotation(Vector3D.PLUS_K, theta, RotationConvention.FRAME_TRANSFORM),
  195.                                       new Vector3D(0, 0, thetaDot));

  196.         // take parametric pole shift into account
  197.         final double xpNeg     = -linearModel(date, polarOffsetXDriver, polarDriftXDriver);
  198.         final double ypNeg     = -linearModel(date, polarOffsetYDriver, polarDriftYDriver);
  199.         final double xpNegDot  = -polarDriftXDriver.getValue();
  200.         final double ypNegDot  = -polarDriftYDriver.getValue();
  201.         final Transform poleShift =
  202.                         new Transform(date,
  203.                                       new Transform(date,
  204.                                                     new Rotation(Vector3D.PLUS_J, xpNeg, RotationConvention.FRAME_TRANSFORM),
  205.                                                     new Vector3D(0.0, xpNegDot, 0.0)),
  206.                                       new Transform(date,
  207.                                                     new Rotation(Vector3D.PLUS_I, ypNeg, RotationConvention.FRAME_TRANSFORM),
  208.                                                     new Vector3D(ypNegDot, 0.0, 0.0)));

  209.         return new Transform(date, meridianShift, poleShift);

  210.     }

  211.     /** {@inheritDoc} */
  212.     @Override
  213.     public StaticTransform getStaticTransform(final AbsoluteDate date) {

  214.         // take parametric prime meridian shift into account
  215.         final double theta    = linearModel(date, primeMeridianOffsetDriver, primeMeridianDriftDriver);
  216.         final StaticTransform meridianShift = StaticTransform.of(
  217.                 date,
  218.                 new Rotation(Vector3D.PLUS_K, theta, RotationConvention.FRAME_TRANSFORM)
  219.         );

  220.         // take parametric pole shift into account
  221.         final double xpNeg     = -linearModel(date, polarOffsetXDriver, polarDriftXDriver);
  222.         final double ypNeg     = -linearModel(date, polarOffsetYDriver, polarDriftYDriver);
  223.         final StaticTransform poleShift = StaticTransform.compose(
  224.                 date,
  225.                 StaticTransform.of(
  226.                         date,
  227.                         new Rotation(Vector3D.PLUS_J, xpNeg, RotationConvention.FRAME_TRANSFORM)),
  228.                 StaticTransform.of(
  229.                         date,
  230.                         new Rotation(Vector3D.PLUS_I, ypNeg, RotationConvention.FRAME_TRANSFORM)));

  231.         return StaticTransform.compose(date, meridianShift, poleShift);

  232.     }

  233.     /** {@inheritDoc} */
  234.     @Override
  235.     public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {

  236.         final T zero = date.getField().getZero();

  237.         // prime meridian shift parameters
  238.         final T theta    = linearModel(date, primeMeridianOffsetDriver, primeMeridianDriftDriver);
  239.         final T thetaDot = zero.newInstance(primeMeridianDriftDriver.getValue());

  240.         // pole shift parameters
  241.         final T xpNeg    = linearModel(date, polarOffsetXDriver, polarDriftXDriver).negate();
  242.         final T ypNeg    = linearModel(date, polarOffsetYDriver, polarDriftYDriver).negate();
  243.         final T xpNegDot = zero.subtract(polarDriftXDriver.getValue());
  244.         final T ypNegDot = zero.subtract(polarDriftYDriver.getValue());

  245.         return getTransform(date, theta, thetaDot, xpNeg, xpNegDot, ypNeg, ypNegDot);

  246.     }

  247.     /** {@inheritDoc} */
  248.     @Override
  249.     public <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {

  250.         // take parametric prime meridian shift into account
  251.         final T theta    = linearModel(date, primeMeridianOffsetDriver, primeMeridianDriftDriver);
  252.         final FieldStaticTransform<T> meridianShift = FieldStaticTransform.of(
  253.                 date,
  254.                 new FieldRotation<>(FieldVector3D.getPlusK(date.getField()), theta, RotationConvention.FRAME_TRANSFORM)
  255.         );

  256.         // take parametric pole shift into account
  257.         final T xpNeg     = linearModel(date, polarOffsetXDriver, polarDriftXDriver).negate();
  258.         final T ypNeg     = linearModel(date, polarOffsetYDriver, polarDriftYDriver).negate();
  259.         final FieldStaticTransform<T> poleShift = FieldStaticTransform.compose(
  260.                 date,
  261.                 FieldStaticTransform.of(
  262.                         date,
  263.                         new FieldRotation<>(FieldVector3D.getPlusJ(date.getField()), xpNeg, RotationConvention.FRAME_TRANSFORM)),
  264.                 FieldStaticTransform.of(
  265.                         date,
  266.                         new FieldRotation<>(FieldVector3D.getPlusI(date.getField()), ypNeg, RotationConvention.FRAME_TRANSFORM)));

  267.         return FieldStaticTransform.compose(date, meridianShift, poleShift);

  268.     }

  269.     /** Get the transform with derivatives.
  270.      * @param date date of the transform
  271.      * @param freeParameters total number of free parameters in the gradient
  272.      * @param indices indices of the estimated parameters in derivatives computations
  273.      * @return computed transform with derivatives
  274.      * @since 10.2
  275.      */
  276.     public FieldTransform<Gradient> getTransform(final FieldAbsoluteDate<Gradient> date,
  277.                                                  final int freeParameters,
  278.                                                  final Map<String, Integer> indices) {

  279.         // prime meridian shift parameters
  280.         final Gradient theta    = linearModel(freeParameters, date,
  281.                                               primeMeridianOffsetDriver, primeMeridianDriftDriver,
  282.                                               indices);
  283.         final Gradient thetaDot = primeMeridianDriftDriver.getValue(freeParameters, indices, date.toAbsoluteDate());

  284.         // pole shift parameters
  285.         final Gradient xpNeg    = linearModel(freeParameters, date,
  286.                                                          polarOffsetXDriver, polarDriftXDriver, indices).negate();
  287.         final Gradient ypNeg    = linearModel(freeParameters, date,
  288.                                                          polarOffsetYDriver, polarDriftYDriver, indices).negate();
  289.         final Gradient xpNegDot = polarDriftXDriver.getValue(freeParameters, indices, date.toAbsoluteDate()).negate();
  290.         final Gradient ypNegDot = polarDriftYDriver.getValue(freeParameters, indices, date.toAbsoluteDate()).negate();

  291.         return getTransform(date, theta, thetaDot, xpNeg, xpNegDot, ypNeg, ypNegDot);

  292.     }

  293.     /** Get the transform with derivatives.
  294.      * @param date date of the transform
  295.      * @param theta angle of the prime meridian
  296.      * @param thetaDot angular rate of the prime meridian
  297.      * @param xpNeg opposite of the angle of the pole motion along X
  298.      * @param xpNegDot opposite of the angular rate of the pole motion along X
  299.      * @param ypNeg opposite of the angle of the pole motion along Y
  300.      * @param ypNegDot opposite of the angular rate of the pole motion along Y
  301.      * @param <T> type of the field elements
  302.      * @return computed transform with derivatives
  303.      */
  304.     private <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date,
  305.                                                                            final T theta, final T thetaDot,
  306.                                                                            final T xpNeg, final T xpNegDot,
  307.                                                                            final T ypNeg, final T ypNegDot) {

  308.         final T                zero  = date.getField().getZero();
  309.         final FieldVector3D<T> plusI = FieldVector3D.getPlusI(date.getField());
  310.         final FieldVector3D<T> plusJ = FieldVector3D.getPlusJ(date.getField());
  311.         final FieldVector3D<T> plusK = FieldVector3D.getPlusK(date.getField());

  312.         // take parametric prime meridian shift into account
  313.         final FieldTransform<T> meridianShift =
  314.                         new FieldTransform<>(date,
  315.                                              new FieldRotation<>(plusK, theta, RotationConvention.FRAME_TRANSFORM),
  316.                                              new FieldVector3D<>(zero, zero, thetaDot));

  317.         // take parametric pole shift into account
  318.         final FieldTransform<T> poleShift =
  319.                         new FieldTransform<>(date,
  320.                                       new FieldTransform<>(date,
  321.                                                            new FieldRotation<>(plusJ, xpNeg, RotationConvention.FRAME_TRANSFORM),
  322.                                                            new FieldVector3D<>(zero, xpNegDot, zero)),
  323.                                       new FieldTransform<>(date,
  324.                                                            new FieldRotation<>(plusI, ypNeg, RotationConvention.FRAME_TRANSFORM),
  325.                                                            new FieldVector3D<>(ypNegDot, zero, zero)));

  326.         return new FieldTransform<>(date, meridianShift, poleShift);

  327.     }

  328.     /** Evaluate a parametric linear model.
  329.      * @param date current date
  330.      * @param offsetDriver driver for the offset parameter
  331.      * @param driftDriver driver for the drift parameter
  332.      * @return current value of the linear model
  333.      */
  334.     private double linearModel(final AbsoluteDate date,
  335.                                final ParameterDriver offsetDriver, final ParameterDriver driftDriver) {
  336.         if (offsetDriver.getReferenceDate() == null) {
  337.             throw new OrekitException(OrekitMessages.NO_REFERENCE_DATE_FOR_PARAMETER,
  338.                                       offsetDriver.getName());
  339.         }
  340.         final double dt     = date.durationFrom(offsetDriver.getReferenceDate());
  341.         final double offset = offsetDriver.getValue();
  342.         final double drift  = driftDriver.getValue();
  343.         return dt * drift + offset;
  344.     }

  345.     /** Evaluate a parametric linear model.
  346.      * @param date current date
  347.      * @param offsetDriver driver for the offset parameter
  348.      * @param driftDriver driver for the drift parameter
  349.      * @return current value of the linear model
  350.      * @param <T> type of the filed elements
  351.      */
  352.     private <T extends CalculusFieldElement<T>> T linearModel(final FieldAbsoluteDate<T> date,
  353.                                                           final ParameterDriver offsetDriver,
  354.                                                           final ParameterDriver driftDriver) {
  355.         if (offsetDriver.getReferenceDate() == null) {
  356.             throw new OrekitException(OrekitMessages.NO_REFERENCE_DATE_FOR_PARAMETER,
  357.                                       offsetDriver.getName());
  358.         }
  359.         final T dt          = date.durationFrom(offsetDriver.getReferenceDate());
  360.         final double offset = offsetDriver.getValue();
  361.         final double drift  = driftDriver.getValue();
  362.         return dt.multiply(drift).add(offset);
  363.     }

  364.     /** Evaluate a parametric linear model.
  365.      * @param freeParameters total number of free parameters in the gradient
  366.      * @param date current date
  367.      * @param offsetDriver driver for the offset parameter
  368.      * @param driftDriver driver for the drift parameter
  369.      * @param indices indices of the estimated parameters in derivatives computations
  370.      * @return current value of the linear model
  371.      * @since 10.2
  372.      */
  373.     private Gradient linearModel(final int freeParameters, final FieldAbsoluteDate<Gradient> date,
  374.                                  final ParameterDriver offsetDriver, final ParameterDriver driftDriver,
  375.                                  final Map<String, Integer> indices) {
  376.         if (offsetDriver.getReferenceDate() == null) {
  377.             throw new OrekitException(OrekitMessages.NO_REFERENCE_DATE_FOR_PARAMETER,
  378.                                       offsetDriver.getName());
  379.         }
  380.         final Gradient dt     = date.durationFrom(offsetDriver.getReferenceDate());
  381.         final Gradient offset = offsetDriver.getValue(freeParameters, indices, date.toAbsoluteDate());
  382.         final Gradient drift  = driftDriver.getValue(freeParameters, indices, date.toAbsoluteDate());
  383.         return dt.multiply(drift).add(offset);
  384.     }

  385.     /** Replace the instance with a data transfer object for serialization.
  386.      * <p>
  387.      * This intermediate class serializes the files supported names, the ephemeris type
  388.      * and the body name.
  389.      * </p>
  390.      * @return data transfer object that will be serialized
  391.      */
  392.     private Object writeReplace() {
  393.         return new DataTransferObject(baseUT1,
  394.                                       primeMeridianOffsetDriver.getValue(),
  395.                                       primeMeridianDriftDriver.getValue(),
  396.                                       polarOffsetXDriver.getValue(),
  397.                                       polarDriftXDriver.getValue(),
  398.                                       polarOffsetYDriver.getValue(),
  399.                                       polarDriftYDriver.getValue());
  400.     }

  401.     /** Local time scale for estimated UT1. */
  402.     private class EstimatedUT1Scale extends UT1Scale {

  403.         /** Serializable UID. */
  404.         private static final long serialVersionUID = 20170922L;

  405.         /** Simple constructor.
  406.          */
  407.         EstimatedUT1Scale() {
  408.             super(baseUT1.getEOPHistory(), baseUT1.getUTCScale());
  409.         }

  410.         /** {@inheritDoc} */
  411.         @Override
  412.         public <T extends CalculusFieldElement<T>> T offsetFromTAI(final FieldAbsoluteDate<T> date) {
  413.             final T dut1 = linearModel(date, primeMeridianOffsetDriver, primeMeridianDriftDriver).divide(EARTH_ANGULAR_VELOCITY);
  414.             return baseUT1.offsetFromTAI(date).add(dut1);
  415.         }

  416.         /** {@inheritDoc} */
  417.         @Override
  418.         public double offsetFromTAI(final AbsoluteDate date) {
  419.             final double dut1 = linearModel(date, primeMeridianOffsetDriver, primeMeridianDriftDriver) / EARTH_ANGULAR_VELOCITY;
  420.             return baseUT1.offsetFromTAI(date) + dut1;
  421.         }

  422.         /** {@inheritDoc} */
  423.         @Override
  424.         public String getName() {
  425.             return baseUT1.getName() + "/estimated";
  426.         }

  427.     }

  428.     /** Internal class used only for serialization. */
  429.     private static class DataTransferObject implements Serializable {

  430.         /** Serializable UID. */
  431.         private static final long serialVersionUID = 20171124L;

  432.         /** Underlying raw UT1. */
  433.         private final UT1Scale baseUT1;

  434.         /** Current prime meridian offset. */
  435.         private final double primeMeridianOffset;

  436.         /** Current prime meridian drift. */
  437.         private final double primeMeridianDrift;

  438.         /** Current pole offset along X. */
  439.         private final double polarOffsetX;

  440.         /** Current pole drift along X. */
  441.         private final double polarDriftX;

  442.         /** Current pole offset along Y. */
  443.         private final double polarOffsetY;

  444.         /** Current pole drift along Y. */
  445.         private final double polarDriftY;

  446.         /** Simple constructor.
  447.          * @param baseUT1 underlying raw UT1
  448.          * @param primeMeridianOffset current prime meridian offset
  449.          * @param primeMeridianDrift current prime meridian drift
  450.          * @param polarOffsetX current pole offset along X
  451.          * @param polarDriftX current pole drift along X
  452.          * @param polarOffsetY current pole offset along Y
  453.          * @param polarDriftY current pole drift along Y
  454.          */
  455.         DataTransferObject(final  UT1Scale baseUT1,
  456.                            final double primeMeridianOffset, final double primeMeridianDrift,
  457.                            final double polarOffsetX,        final double polarDriftX,
  458.                            final double polarOffsetY,        final double polarDriftY) {
  459.             this.baseUT1             = baseUT1;
  460.             this.primeMeridianOffset = primeMeridianOffset;
  461.             this.primeMeridianDrift  = primeMeridianDrift;
  462.             this.polarOffsetX        = polarOffsetX;
  463.             this.polarDriftX         = polarDriftX;
  464.             this.polarOffsetY        = polarOffsetY;
  465.             this.polarDriftY         = polarDriftY;
  466.         }

  467.         /** Replace the deserialized data transfer object with a {@link EstimatedEarthFrameProvider}.
  468.          * @return replacement {@link EstimatedEarthFrameProvider}
  469.          */
  470.         private Object readResolve() {
  471.             try {
  472.                 final EstimatedEarthFrameProvider provider = new EstimatedEarthFrameProvider(baseUT1);
  473.                 provider.getPrimeMeridianOffsetDriver().setValue(primeMeridianOffset);
  474.                 provider.getPrimeMeridianDriftDriver().setValue(primeMeridianDrift);
  475.                 provider.getPolarOffsetXDriver().setValue(polarOffsetX);
  476.                 provider.getPolarDriftXDriver().setValue(polarDriftX);
  477.                 provider.getPolarOffsetYDriver().setValue(polarOffsetY);
  478.                 provider.getPolarDriftYDriver().setValue(polarDriftY);
  479.                 return provider;
  480.             } catch (OrekitException oe) {
  481.                 // this should never happen as values already come from previous drivers
  482.                 throw new OrekitInternalError(oe);
  483.             }
  484.         }

  485.     }

  486. }