TimeStampedFieldPVCoordinates.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.utils;

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

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

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

  39.     /** The date. */
  40.     private final FieldAbsoluteDate<T> date;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  552.     /** Get the date.
  553.      * @return date
  554.      */
  555.     public FieldAbsoluteDate<T> getDate() {
  556.         return date;
  557.     }

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

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

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

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

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

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

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

  675.         // build a new interpolated instance

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

  680.     }

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

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

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

  711. }