TimeStampedFieldPVCoordinates.java

  1. /* Copyright 2002-2022 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.utils;

  18. import java.util.Collection;
  19. import java.util.stream.Stream;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.hipparchus.analysis.differentiation.FieldDerivative;
  22. import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
  23. import org.hipparchus.analysis.interpolation.FieldHermiteInterpolator;
  24. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  25. import org.orekit.annotation.DefaultDataContext;
  26. import org.orekit.data.DataContext;
  27. import org.orekit.errors.OrekitInternalError;
  28. import org.orekit.time.AbsoluteDate;
  29. import org.orekit.time.FieldAbsoluteDate;
  30. import org.orekit.time.FieldTimeStamped;
  31. import org.orekit.time.TimeScale;
  32. import org.orekit.time.TimeStamped;

  33. /** {@link TimeStamped time-stamped} version of {@link FieldPVCoordinates}.
  34.  * <p>Instances of this class are guaranteed to be immutable.</p>
  35.  * @param <T> the type of the field elements
  36.  * @author Luc Maisonobe
  37.  * @since 7.0
  38.  */
  39. public class TimeStampedFieldPVCoordinates<T extends CalculusFieldElement<T>>
  40.     extends FieldPVCoordinates<T> implements FieldTimeStamped<T> {

  41.     /** The date. */
  42.     private final FieldAbsoluteDate<T> date;

  43.     /** Builds a PVCoordinates pair.
  44.      * @param date coordinates date
  45.      * @param position the position vector (m)
  46.      * @param velocity the velocity vector (m/s)
  47.      * @param acceleration the acceleration vector (m/s²)
  48.      */
  49.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  50.                                          final FieldVector3D<T> position,
  51.                                          final FieldVector3D<T> velocity,
  52.                                          final FieldVector3D<T> acceleration) {
  53.         this(new FieldAbsoluteDate<>(position.getX().getField(), date),
  54.              position, velocity, acceleration);
  55.     }

  56.     /** Builds a PVCoordinates pair.
  57.      * @param date coordinates date
  58.      * @param position the position vector (m)
  59.      * @param velocity the velocity vector (m/s)
  60.      * @param acceleration the acceleration vector (m/s²)
  61.      */
  62.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  63.                                          final FieldVector3D<T> position,
  64.                                          final FieldVector3D<T> velocity,
  65.                                          final FieldVector3D<T> acceleration) {
  66.         super(position, velocity, acceleration);
  67.         this.date = date;
  68.     }

  69.     /** Basic constructor.
  70.      * <p>Build a PVCoordinates from another one at a given date</p>
  71.      * <p>The PVCoordinates built will be pv</p>
  72.      * @param date date of the built coordinates
  73.      * @param pv base (unscaled) PVCoordinates
  74.      */
  75.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date, final FieldPVCoordinates<T> pv) {
  76.         this(new FieldAbsoluteDate<>(pv.getPosition().getX().getField(), date), pv);
  77.     }

  78.     /** Basic constructor.
  79.      * <p>Build a PVCoordinates from another one at a given date</p>
  80.      * <p>The PVCoordinates built will be pv</p>
  81.      * @param date date of the built coordinates
  82.      * @param pv base (unscaled) PVCoordinates
  83.      */
  84.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date, final FieldPVCoordinates<T> pv) {
  85.         super(pv.getPosition(),
  86.               pv.getVelocity(),
  87.               pv.getAcceleration());
  88.         this.date = date;
  89.     }

  90.     /** Multiplicative constructor
  91.      * <p>Build a PVCoordinates from another one and a scale factor.</p>
  92.      * <p>The PVCoordinates built will be a * pv</p>
  93.      * @param date date of the built coordinates
  94.      * @param a scale factor
  95.      * @param pv base (unscaled) PVCoordinates
  96.      */
  97.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  98.                                          final double a, final FieldPVCoordinates<T> pv) {
  99.         this(new FieldAbsoluteDate<>(pv.getPosition().getX().getField(), date), a, pv);
  100.     }

  101.     /** Multiplicative constructor
  102.      * <p>Build a PVCoordinates from another one and a scale factor.</p>
  103.      * <p>The PVCoordinates built will be a * pv</p>
  104.      * @param date date of the built coordinates
  105.      * @param a scale factor
  106.      * @param pv base (unscaled) PVCoordinates
  107.      */
  108.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  109.                                          final double a, final FieldPVCoordinates<T> pv) {
  110.         super(new FieldVector3D<>(a, pv.getPosition()),
  111.               new FieldVector3D<>(a, pv.getVelocity()),
  112.               new FieldVector3D<>(a, pv.getAcceleration()));
  113.         this.date = date;
  114.     }

  115.     /** Multiplicative constructor
  116.      * <p>Build a PVCoordinates from another one and a scale factor.</p>
  117.      * <p>The PVCoordinates built will be a * pv</p>
  118.      * @param date date of the built coordinates
  119.      * @param a scale factor
  120.      * @param pv base (unscaled) PVCoordinates
  121.      */
  122.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  123.                                          final T a, final FieldPVCoordinates<T> pv) {
  124.         this(new FieldAbsoluteDate<>(a.getField(), date), a, pv);
  125.     }

  126.     /** Multiplicative constructor
  127.      * <p>Build a PVCoordinates from another one and a scale factor.</p>
  128.      * <p>The PVCoordinates built will be a * pv</p>
  129.      * @param date date of the built coordinates
  130.      * @param a scale factor
  131.      * @param pv base (unscaled) PVCoordinates
  132.      */
  133.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  134.                                          final T a, final FieldPVCoordinates<T> pv) {
  135.         super(new FieldVector3D<>(a, pv.getPosition()),
  136.               new FieldVector3D<>(a, pv.getVelocity()),
  137.               new FieldVector3D<>(a, pv.getAcceleration()));
  138.         this.date = date;
  139.     }

  140.     /** Multiplicative constructor
  141.      * <p>Build a PVCoordinates from another one and a scale factor.</p>
  142.      * <p>The PVCoordinates built will be a * pv</p>
  143.      * @param date date of the built coordinates
  144.      * @param a scale factor
  145.      * @param pv base (unscaled) PVCoordinates
  146.      */
  147.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  148.                                          final T a, final PVCoordinates pv) {
  149.         this(new FieldAbsoluteDate<>(a.getField(), date), a, pv);
  150.     }

  151.     /** Multiplicative constructor
  152.      * <p>Build a PVCoordinates from another one and a scale factor.</p>
  153.      * <p>The PVCoordinates built will be a * pv</p>
  154.      * @param date date of the built coordinates
  155.      * @param a scale factor
  156.      * @param pv base (unscaled) PVCoordinates
  157.      */
  158.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  159.                                          final T a, final PVCoordinates pv) {
  160.         super(new FieldVector3D<>(a, pv.getPosition()),
  161.               new FieldVector3D<>(a, pv.getVelocity()),
  162.               new FieldVector3D<>(a, pv.getAcceleration()));
  163.         this.date = date;
  164.     }

  165.     /** Subtractive constructor
  166.      * <p>Build a relative PVCoordinates from a start and an end position.</p>
  167.      * <p>The PVCoordinates built will be end - start.</p>
  168.      * @param date date of the built coordinates
  169.      * @param start Starting PVCoordinates
  170.      * @param end ending PVCoordinates
  171.      */
  172.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  173.                                          final FieldPVCoordinates<T> start, final FieldPVCoordinates<T> end) {
  174.         this(new FieldAbsoluteDate<>(start.getPosition().getX().getField(), date), start, end);
  175.     }

  176.     /** Subtractive constructor
  177.      * <p>Build a relative PVCoordinates from a start and an end position.</p>
  178.      * <p>The PVCoordinates built will be end - start.</p>
  179.      * @param date date of the built coordinates
  180.      * @param start Starting PVCoordinates
  181.      * @param end ending PVCoordinates
  182.      */
  183.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  184.                                          final FieldPVCoordinates<T> start, final FieldPVCoordinates<T> end) {
  185.         super(end.getPosition().subtract(start.getPosition()),
  186.               end.getVelocity().subtract(start.getVelocity()),
  187.               end.getAcceleration().subtract(start.getAcceleration()));
  188.         this.date = date;
  189.     }

  190.     /** Linear constructor
  191.      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
  192.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
  193.      * @param date date of the built coordinates
  194.      * @param a1 first scale factor
  195.      * @param pv1 first base (unscaled) PVCoordinates
  196.      * @param a2 second scale factor
  197.      * @param pv2 second base (unscaled) PVCoordinates
  198.      */
  199.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  200.                                          final double a1, final FieldPVCoordinates<T> pv1,
  201.                                          final double a2, final FieldPVCoordinates<T> pv2) {
  202.         this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
  203.              a1, pv1, a2, pv2);
  204.     }

  205.     /** Linear constructor
  206.      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
  207.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
  208.      * @param date date of the built coordinates
  209.      * @param a1 first scale factor
  210.      * @param pv1 first base (unscaled) PVCoordinates
  211.      * @param a2 second scale factor
  212.      * @param pv2 second base (unscaled) PVCoordinates
  213.      */
  214.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  215.                                          final double a1, final FieldPVCoordinates<T> pv1,
  216.                                          final double a2, final FieldPVCoordinates<T> pv2) {
  217.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition()),
  218.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity()),
  219.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
  220.         this.date = date;
  221.     }

  222.     /** Linear constructor
  223.      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
  224.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
  225.      * @param date date of the built coordinates
  226.      * @param a1 first scale factor
  227.      * @param pv1 first base (unscaled) PVCoordinates
  228.      * @param a2 second scale factor
  229.      * @param pv2 second base (unscaled) PVCoordinates
  230.      */
  231.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  232.                                          final T a1, final FieldPVCoordinates<T> pv1,
  233.                                          final T a2, final FieldPVCoordinates<T> pv2) {
  234.         this(new FieldAbsoluteDate<>(a1.getField(), date),
  235.              a1, pv1, a2, pv2);
  236.     }

  237.     /** Linear constructor
  238.      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
  239.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
  240.      * @param date date of the built coordinates
  241.      * @param a1 first scale factor
  242.      * @param pv1 first base (unscaled) PVCoordinates
  243.      * @param a2 second scale factor
  244.      * @param pv2 second base (unscaled) PVCoordinates
  245.      */
  246.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  247.                                          final T a1, final FieldPVCoordinates<T> pv1,
  248.                                          final T a2, final FieldPVCoordinates<T> pv2) {
  249.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition()),
  250.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity()),
  251.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
  252.         this.date = date;
  253.     }

  254.     /** Linear constructor
  255.      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
  256.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
  257.      * @param date date of the built coordinates
  258.      * @param a1 first scale factor
  259.      * @param pv1 first base (unscaled) PVCoordinates
  260.      * @param a2 second scale factor
  261.      * @param pv2 second base (unscaled) PVCoordinates
  262.      */
  263.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  264.                                          final T a1, final PVCoordinates pv1,
  265.                                          final T a2, final PVCoordinates pv2) {
  266.         this(new FieldAbsoluteDate<>(a1.getField(), date),
  267.              a1, pv1, a2, pv2);
  268.     }

  269.     /** Linear constructor
  270.      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
  271.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
  272.      * @param date date of the built coordinates
  273.      * @param a1 first scale factor
  274.      * @param pv1 first base (unscaled) PVCoordinates
  275.      * @param a2 second scale factor
  276.      * @param pv2 second base (unscaled) PVCoordinates
  277.      */
  278.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  279.                                          final T a1, final PVCoordinates pv1,
  280.                                          final T a2, final PVCoordinates pv2) {
  281.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition()),
  282.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity()),
  283.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
  284.         this.date = date;
  285.     }

  286.     /** Linear constructor
  287.      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
  288.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  289.      * @param date date of the built coordinates
  290.      * @param a1 first scale factor
  291.      * @param pv1 first base (unscaled) PVCoordinates
  292.      * @param a2 second scale factor
  293.      * @param pv2 second base (unscaled) PVCoordinates
  294.      * @param a3 third scale factor
  295.      * @param pv3 third base (unscaled) PVCoordinates
  296.      */
  297.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  298.                                          final double a1, final FieldPVCoordinates<T> pv1,
  299.                                          final double a2, final FieldPVCoordinates<T> pv2,
  300.                                          final double a3, final FieldPVCoordinates<T> pv3) {
  301.         this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
  302.              a1, pv1, a2, pv2, a3, pv3);
  303.     }

  304.     /** Linear constructor
  305.      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
  306.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  307.      * @param date date of the built coordinates
  308.      * @param a1 first scale factor
  309.      * @param pv1 first base (unscaled) PVCoordinates
  310.      * @param a2 second scale factor
  311.      * @param pv2 second base (unscaled) PVCoordinates
  312.      * @param a3 third scale factor
  313.      * @param pv3 third base (unscaled) PVCoordinates
  314.      */
  315.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  316.                                          final double a1, final FieldPVCoordinates<T> pv1,
  317.                                          final double a2, final FieldPVCoordinates<T> pv2,
  318.                                          final double a3, final FieldPVCoordinates<T> pv3) {
  319.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),     a3, pv3.getPosition()),
  320.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),     a3, pv3.getVelocity()),
  321.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
  322.         this.date = date;
  323.     }

  324.     /** Linear constructor
  325.      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
  326.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  327.      * @param date date of the built coordinates
  328.      * @param a1 first scale factor
  329.      * @param pv1 first base (unscaled) PVCoordinates
  330.      * @param a2 second scale factor
  331.      * @param pv2 second base (unscaled) PVCoordinates
  332.      * @param a3 third scale factor
  333.      * @param pv3 third base (unscaled) PVCoordinates
  334.      */
  335.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  336.                                          final T a1, final FieldPVCoordinates<T> pv1,
  337.                                          final T a2, final FieldPVCoordinates<T> pv2,
  338.                                          final T a3, final FieldPVCoordinates<T> pv3) {
  339.         this(new FieldAbsoluteDate<>(a1.getField(), date),
  340.              a1, pv1, a2, pv2, a3, pv3);
  341.     }

  342.     /** Linear constructor
  343.      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
  344.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  345.      * @param date date of the built coordinates
  346.      * @param a1 first scale factor
  347.      * @param pv1 first base (unscaled) PVCoordinates
  348.      * @param a2 second scale factor
  349.      * @param pv2 second base (unscaled) PVCoordinates
  350.      * @param a3 third scale factor
  351.      * @param pv3 third base (unscaled) PVCoordinates
  352.      */
  353.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  354.                                          final T a1, final FieldPVCoordinates<T> pv1,
  355.                                          final T a2, final FieldPVCoordinates<T> pv2,
  356.                                          final T a3, final FieldPVCoordinates<T> pv3) {
  357.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),     a3, pv3.getPosition()),
  358.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),     a3, pv3.getVelocity()),
  359.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
  360.         this.date = date;
  361.     }

  362.     /** Linear constructor
  363.      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
  364.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  365.      * @param date date of the built coordinates
  366.      * @param a1 first scale factor
  367.      * @param pv1 first base (unscaled) PVCoordinates
  368.      * @param a2 second scale factor
  369.      * @param pv2 second base (unscaled) PVCoordinates
  370.      * @param a3 third scale factor
  371.      * @param pv3 third base (unscaled) PVCoordinates
  372.      */
  373.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  374.                                          final T a1, final PVCoordinates pv1,
  375.                                          final T a2, final PVCoordinates pv2,
  376.                                          final T a3, final PVCoordinates pv3) {
  377.         this(new FieldAbsoluteDate<>(a1.getField(), date),
  378.              a1, pv1, a2, pv2, a3, pv3);
  379.     }

  380.     /** Linear constructor
  381.      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
  382.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  383.      * @param date date of the built coordinates
  384.      * @param a1 first scale factor
  385.      * @param pv1 first base (unscaled) PVCoordinates
  386.      * @param a2 second scale factor
  387.      * @param pv2 second base (unscaled) PVCoordinates
  388.      * @param a3 third scale factor
  389.      * @param pv3 third base (unscaled) PVCoordinates
  390.      */
  391.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  392.                                          final T a1, final PVCoordinates pv1,
  393.                                          final T a2, final PVCoordinates pv2,
  394.                                          final T a3, final PVCoordinates pv3) {
  395.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),     a3, pv3.getPosition()),
  396.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),     a3, pv3.getVelocity()),
  397.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
  398.         this.date = date;
  399.     }

  400.     /** Linear constructor
  401.      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
  402.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  403.      * @param date date of the built coordinates
  404.      * @param a1 first scale factor
  405.      * @param pv1 first base (unscaled) PVCoordinates
  406.      * @param a2 second scale factor
  407.      * @param pv2 second base (unscaled) PVCoordinates
  408.      * @param a3 third scale factor
  409.      * @param pv3 third base (unscaled) PVCoordinates
  410.      * @param a4 fourth scale factor
  411.      * @param pv4 fourth base (unscaled) PVCoordinates
  412.      */
  413.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  414.                                          final double a1, final FieldPVCoordinates<T> pv1,
  415.                                          final double a2, final FieldPVCoordinates<T> pv2,
  416.                                          final double a3, final FieldPVCoordinates<T> pv3,
  417.                                          final double a4, final FieldPVCoordinates<T> pv4) {
  418.         this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
  419.              a1, pv1, a2, pv2, a3, pv3, a4, pv4);
  420.     }

  421.     /** Linear constructor
  422.      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
  423.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  424.      * @param date date of the built coordinates
  425.      * @param a1 first scale factor
  426.      * @param pv1 first base (unscaled) PVCoordinates
  427.      * @param a2 second scale factor
  428.      * @param pv2 second base (unscaled) PVCoordinates
  429.      * @param a3 third scale factor
  430.      * @param pv3 third base (unscaled) PVCoordinates
  431.      * @param a4 fourth scale factor
  432.      * @param pv4 fourth base (unscaled) PVCoordinates
  433.      */
  434.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  435.                                          final double a1, final FieldPVCoordinates<T> pv1,
  436.                                          final double a2, final FieldPVCoordinates<T> pv2,
  437.                                          final double a3, final FieldPVCoordinates<T> pv3,
  438.                                          final double a4, final FieldPVCoordinates<T> pv4) {
  439.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),
  440.                                   a3, pv3.getPosition(),     a4, pv4.getPosition()),
  441.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),
  442.                                   a3, pv3.getVelocity(),     a4, pv4.getVelocity()),
  443.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
  444.                                   a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
  445.         this.date = date;
  446.     }

  447.     /** Linear constructor
  448.      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
  449.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  450.      * @param date date of the built coordinates
  451.      * @param a1 first scale factor
  452.      * @param pv1 first base (unscaled) PVCoordinates
  453.      * @param a2 second scale factor
  454.      * @param pv2 second base (unscaled) PVCoordinates
  455.      * @param a3 third scale factor
  456.      * @param pv3 third base (unscaled) PVCoordinates
  457.      * @param a4 fourth scale factor
  458.      * @param pv4 fourth base (unscaled) PVCoordinates
  459.      */
  460.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  461.                                          final T a1, final FieldPVCoordinates<T> pv1,
  462.                                          final T a2, final FieldPVCoordinates<T> pv2,
  463.                                          final T a3, final FieldPVCoordinates<T> pv3,
  464.                                          final T a4, final FieldPVCoordinates<T> pv4) {
  465.         this(new FieldAbsoluteDate<>(a1.getField(), date),
  466.              a1, pv1, a2, pv2, a3, pv3, a4, pv4);
  467.     }

  468.     /** Linear constructor
  469.      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
  470.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  471.      * @param date date of the built coordinates
  472.      * @param a1 first scale factor
  473.      * @param pv1 first base (unscaled) PVCoordinates
  474.      * @param a2 second scale factor
  475.      * @param pv2 second base (unscaled) PVCoordinates
  476.      * @param a3 third scale factor
  477.      * @param pv3 third base (unscaled) PVCoordinates
  478.      * @param a4 fourth scale factor
  479.      * @param pv4 fourth base (unscaled) PVCoordinates
  480.      */
  481.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  482.                                          final T a1, final FieldPVCoordinates<T> pv1,
  483.                                          final T a2, final FieldPVCoordinates<T> pv2,
  484.                                          final T a3, final FieldPVCoordinates<T> pv3,
  485.                                          final T a4, final FieldPVCoordinates<T> pv4) {
  486.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),
  487.                                   a3, pv3.getPosition(),     a4, pv4.getPosition()),
  488.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),
  489.                                   a3, pv3.getVelocity(),     a4, pv4.getVelocity()),
  490.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
  491.                                   a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
  492.         this.date = date;
  493.     }

  494.     /** Linear constructor
  495.      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
  496.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  497.      * @param date date of the built coordinates
  498.      * @param a1 first scale factor
  499.      * @param pv1 first base (unscaled) PVCoordinates
  500.      * @param a2 second scale factor
  501.      * @param pv2 second base (unscaled) PVCoordinates
  502.      * @param a3 third scale factor
  503.      * @param pv3 third base (unscaled) PVCoordinates
  504.      * @param a4 fourth scale factor
  505.      * @param pv4 fourth base (unscaled) PVCoordinates
  506.      */
  507.     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
  508.                                          final T a1, final PVCoordinates pv1,
  509.                                          final T a2, final PVCoordinates pv2,
  510.                                          final T a3, final PVCoordinates pv3,
  511.                                          final T a4, final PVCoordinates pv4) {
  512.         this(new FieldAbsoluteDate<>(a1.getField(), date),
  513.              a1, pv1, a2, pv2, a3, pv3, a4, pv4);
  514.     }

  515.     /** Linear constructor
  516.      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
  517.      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  518.      * @param date date of the built coordinates
  519.      * @param a1 first scale factor
  520.      * @param pv1 first base (unscaled) PVCoordinates
  521.      * @param a2 second scale factor
  522.      * @param pv2 second base (unscaled) PVCoordinates
  523.      * @param a3 third scale factor
  524.      * @param pv3 third base (unscaled) PVCoordinates
  525.      * @param a4 fourth scale factor
  526.      * @param pv4 fourth base (unscaled) PVCoordinates
  527.      */
  528.     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  529.                                          final T a1, final PVCoordinates pv1,
  530.                                          final T a2, final PVCoordinates pv2,
  531.                                          final T a3, final PVCoordinates pv3,
  532.                                          final T a4, final PVCoordinates pv4) {
  533.         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),
  534.                                   a3, pv3.getPosition(),     a4, pv4.getPosition()),
  535.               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),
  536.                                   a3, pv3.getVelocity(),     a4, pv4.getVelocity()),
  537.               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
  538.                                   a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
  539.         this.date = date;
  540.     }

  541.     /** Builds a TimeStampedFieldPVCoordinates triplet from  a {@link FieldVector3D}&lt;{@link FieldDerivativeStructure}&gt;.
  542.      * <p>
  543.      * The vector components must have time as their only derivation parameter and
  544.      * have consistent derivation orders.
  545.      * </p>
  546.      * @param date date of the built coordinates
  547.      * @param <U> type of the derivative
  548.      * @param p vector with time-derivatives embedded within the coordinates
  549.      */
  550.     public <U extends FieldDerivative<T, U>> TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
  551.                                                                            final FieldVector3D<U> p) {
  552.         super(p);
  553.         this.date = date;
  554.     }

  555.     /** {@inheritDoc} */
  556.     @Override
  557.     public FieldAbsoluteDate<T> getDate() {
  558.         return date;
  559.     }

  560.     /** Get a time-shifted state.
  561.      * <p>
  562.      * The state can be slightly shifted to close dates. This shift is based on
  563.      * a simple linear model. It is <em>not</em> intended as a replacement for
  564.      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
  565.      * for either small time shifts or coarse accuracy.
  566.      * </p>
  567.      * @param dt time shift in seconds
  568.      * @return a new state, shifted with respect to the instance (which is immutable)
  569.      */
  570.     public TimeStampedFieldPVCoordinates<T> shiftedBy(final double dt) {
  571.         final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
  572.         return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
  573.                                                    spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
  574.     }

  575.     /** Get a time-shifted state.
  576.      * <p>
  577.      * The state can be slightly shifted to close dates. This shift is based on
  578.      * a simple linear model. It is <em>not</em> intended as a replacement for
  579.      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
  580.      * for either small time shifts or coarse accuracy.
  581.      * </p>
  582.      * @param dt time shift in seconds
  583.      * @return a new state, shifted with respect to the instance (which is immutable)
  584.      */
  585.     public TimeStampedFieldPVCoordinates<T> shiftedBy(final T dt) {
  586.         final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
  587.         return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
  588.                                                    spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
  589.     }

  590.     /** Interpolate position-velocity.
  591.      * <p>
  592.      * The interpolated instance is created by polynomial Hermite interpolation
  593.      * ensuring velocity remains the exact derivative of position.
  594.      * </p>
  595.      * <p>
  596.      * Note that even if first time derivatives (velocities)
  597.      * from sample can be ignored, the interpolated instance always includes
  598.      * interpolated derivatives. This feature can be used explicitly to
  599.      * compute these derivatives when it would be too complex to compute them
  600.      * from an analytical formula: just compute a few sample points from the
  601.      * explicit formula and set the derivatives to zero in these sample points,
  602.      * then use interpolation to add derivatives consistent with the positions.
  603.      * </p>
  604.      * @param date interpolation date
  605.      * @param filter filter for derivatives from the sample to use in interpolation
  606.      * @param sample sample points on which interpolation should be done
  607.      * @param <T> the type of the field elements
  608.      * @return a new position-velocity, interpolated at specified date
  609.      */
  610.     public static <T extends CalculusFieldElement<T>>
  611.         TimeStampedFieldPVCoordinates<T> interpolate(final FieldAbsoluteDate<T> date,
  612.                                                      final CartesianDerivativesFilter filter,
  613.                                                      final Collection<TimeStampedFieldPVCoordinates<T>> sample) {
  614.         return interpolate(date, filter, sample.stream());
  615.     }

  616.     /** Interpolate position-velocity.
  617.      * <p>
  618.      * The interpolated instance is created by polynomial Hermite interpolation
  619.      * ensuring velocity remains the exact derivative of position.
  620.      * </p>
  621.      * <p>
  622.      * Note that even if first time derivatives (velocities)
  623.      * from sample can be ignored, the interpolated instance always includes
  624.      * interpolated derivatives. This feature can be used explicitly to
  625.      * compute these derivatives when it would be too complex to compute them
  626.      * from an analytical formula: just compute a few sample points from the
  627.      * explicit formula and set the derivatives to zero in these sample points,
  628.      * then use interpolation to add derivatives consistent with the positions.
  629.      * </p>
  630.      * @param date interpolation date
  631.      * @param filter filter for derivatives from the sample to use in interpolation
  632.      * @param sample sample points on which interpolation should be done
  633.      * @param <T> the type of the field elements
  634.      * @return a new position-velocity, interpolated at specified date
  635.      */
  636.     public static <T extends CalculusFieldElement<T>>
  637.         TimeStampedFieldPVCoordinates<T> interpolate(final FieldAbsoluteDate<T> date,
  638.                                                      final CartesianDerivativesFilter filter,
  639.                                                      final Stream<TimeStampedFieldPVCoordinates<T>> sample) {

  640.         // set up an interpolator taking derivatives into account
  641.         final FieldHermiteInterpolator<T> interpolator = new FieldHermiteInterpolator<>();

  642.         // add sample points
  643.         switch (filter) {
  644.             case USE_P :
  645.                 // populate sample with position data, ignoring velocity
  646.                 sample.forEach(pv -> {
  647.                     final FieldVector3D<T> position = pv.getPosition();
  648.                     interpolator.addSamplePoint(pv.getDate().durationFrom(date),
  649.                                                 position.toArray());
  650.                 });
  651.                 break;
  652.             case USE_PV :
  653.                 // populate sample with position and velocity data
  654.                 sample.forEach(pv -> {
  655.                     final FieldVector3D<T> position = pv.getPosition();
  656.                     final FieldVector3D<T> velocity = pv.getVelocity();
  657.                     interpolator.addSamplePoint(pv.getDate().durationFrom(date),
  658.                                                 position.toArray(), velocity.toArray());
  659.                 });
  660.                 break;
  661.             case USE_PVA :
  662.                 // populate sample with position, velocity and acceleration data
  663.                 sample.forEach(pv -> {
  664.                     final FieldVector3D<T> position     = pv.getPosition();
  665.                     final FieldVector3D<T> velocity     = pv.getVelocity();
  666.                     final FieldVector3D<T> acceleration = pv.getAcceleration();
  667.                     interpolator.addSamplePoint(pv.getDate().durationFrom(date),
  668.                                                 position.toArray(), velocity.toArray(), acceleration.toArray());
  669.                 });
  670.                 break;
  671.             default :
  672.                 // this should never happen
  673.                 throw new OrekitInternalError(null);
  674.         }

  675.         // interpolate
  676.         final T[][] p = interpolator.derivatives(date.getField().getZero(), 2);

  677.         // build a new interpolated instance

  678.         return new TimeStampedFieldPVCoordinates<>(date,
  679.                                                    new FieldVector3D<>(p[0]),
  680.                                                    new FieldVector3D<>(p[1]),
  681.                                                    new FieldVector3D<>(p[2]));

  682.     }

  683.     /** Convert to a constant position-velocity.
  684.      * @return a constant position-velocity
  685.      * @since 9.0
  686.      */
  687.     public TimeStampedPVCoordinates toTimeStampedPVCoordinates() {
  688.         return new TimeStampedPVCoordinates(date.toAbsoluteDate(),
  689.                                             getPosition().toVector3D(),
  690.                                             getVelocity().toVector3D(),
  691.                                             getAcceleration().toVector3D());
  692.     }

  693.     /** Return a string representation of this date, position, velocity, and acceleration.
  694.      *
  695.      * <p>This method uses the {@link DataContext#getDefault() default data context}.
  696.      *
  697.      * @return string representation of this.
  698.      */
  699.     @Override
  700.     @DefaultDataContext
  701.     public String toString() {
  702.         return toTimeStampedPVCoordinates().toString();
  703.     }

  704.     /**
  705.      * Return a string representation of this date, position, velocity, and acceleration.
  706.      *
  707.      * @param utc time scale used to print the date.
  708.      * @return string representation of this.
  709.      */
  710.     public String toString(final TimeScale utc) {
  711.         return toTimeStampedPVCoordinates().toString(utc);
  712.     }

  713. }