TimeStampedFieldPVCoordinates.java

  1. /* Copyright 2002-2017 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.interpolation.FieldHermiteInterpolator;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.orekit.errors.OrekitInternalError;
  24. import org.orekit.time.AbsoluteDate;
  25. import org.orekit.time.FieldAbsoluteDate;
  26. import org.orekit.time.TimeStamped;

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

  35.     /** The date. */
  36.     private final FieldAbsoluteDate<T> date;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  535.     /** Get the date.
  536.      * @return date
  537.      */
  538.     public FieldAbsoluteDate<T> getDate() {
  539.         return date;
  540.     }

  541.     /** Get a time-shifted state.
  542.      * <p>
  543.      * The state can be slightly shifted to close dates. This shift is based on
  544.      * a simple linear model. It is <em>not</em> intended as a replacement for
  545.      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
  546.      * for either small time shifts or coarse accuracy.
  547.      * </p>
  548.      * @param dt time shift in seconds
  549.      * @return a new state, shifted with respect to the instance (which is immutable)
  550.      */
  551.     public TimeStampedFieldPVCoordinates<T> shiftedBy(final double dt) {
  552.         final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
  553.         return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
  554.                                                    spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
  555.     }

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

  571.     /** Interpolate position-velocity.
  572.      * <p>
  573.      * The interpolated instance is created by polynomial Hermite interpolation
  574.      * ensuring velocity remains the exact derivative of position.
  575.      * </p>
  576.      * <p>
  577.      * Note that even if first time derivatives (velocities)
  578.      * from sample can be ignored, the interpolated instance always includes
  579.      * interpolated derivatives. This feature can be used explicitly to
  580.      * compute these derivatives when it would be too complex to compute them
  581.      * from an analytical formula: just compute a few sample points from the
  582.      * explicit formula and set the derivatives to zero in these sample points,
  583.      * then use interpolation to add derivatives consistent with the positions.
  584.      * </p>
  585.      * @param date interpolation date
  586.      * @param filter filter for derivatives from the sample to use in interpolation
  587.      * @param sample sample points on which interpolation should be done
  588.      * @param <T> the type of the field elements
  589.      * @return a new position-velocity, interpolated at specified date
  590.      */
  591.     public static <T extends RealFieldElement<T>>
  592.         TimeStampedFieldPVCoordinates<T> interpolate(final FieldAbsoluteDate<T> date,
  593.                                                      final CartesianDerivativesFilter filter,
  594.                                                      final Collection<TimeStampedFieldPVCoordinates<T>> sample) {
  595.         return interpolate(date, filter, sample.stream());
  596.     }

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

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

  623.         // add sample points
  624.         switch (filter) {
  625.             case USE_P :
  626.                 // populate sample with position data, ignoring velocity
  627.                 sample.forEach(pv -> {
  628.                     final FieldVector3D<T> position = pv.getPosition();
  629.                     interpolator.addSamplePoint(pv.getDate().durationFrom(date),
  630.                                                 position.toArray());
  631.                 });
  632.                 break;
  633.             case USE_PV :
  634.                 // populate sample with position and velocity data
  635.                 sample.forEach(pv -> {
  636.                     final FieldVector3D<T> position = pv.getPosition();
  637.                     final FieldVector3D<T> velocity = pv.getVelocity();
  638.                     interpolator.addSamplePoint(pv.getDate().durationFrom(date),
  639.                                                 position.toArray(), velocity.toArray());
  640.                 });
  641.                 break;
  642.             case USE_PVA :
  643.                 // populate sample with position, velocity and acceleration data
  644.                 sample.forEach(pv -> {
  645.                     final FieldVector3D<T> position     = pv.getPosition();
  646.                     final FieldVector3D<T> velocity     = pv.getVelocity();
  647.                     final FieldVector3D<T> acceleration = pv.getAcceleration();
  648.                     interpolator.addSamplePoint(pv.getDate().durationFrom(date),
  649.                                                 position.toArray(), velocity.toArray(), acceleration.toArray());
  650.                 });
  651.                 break;
  652.             default :
  653.                 // this should never happen
  654.                 throw new OrekitInternalError(null);
  655.         }

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

  658.         // build a new interpolated instance

  659.         return new TimeStampedFieldPVCoordinates<>(date,
  660.                                                    new FieldVector3D<>(p[0]),
  661.                                                    new FieldVector3D<>(p[1]),
  662.                                                    new FieldVector3D<>(p[2]));

  663.     }

  664.     /** Convert to a constant position-velocity.
  665.      * @return a constant position-velocity
  666.      * @since 9.0
  667.      */
  668.     public TimeStampedPVCoordinates toTimeStampedPVCoordinates() {
  669.         return new TimeStampedPVCoordinates(date.toAbsoluteDate(),
  670.                                             getPosition().toVector3D(),
  671.                                             getVelocity().toVector3D(),
  672.                                             getAcceleration().toVector3D());
  673.     }

  674.     /** Return a string representation of this position/velocity pair.
  675.      * @return string representation of this position/velocity pair
  676.      */
  677.     public String toString() {
  678.         final String comma = ", ";
  679.         return new StringBuffer().append('{').append(date).append(", P(").
  680.                                   append(getPosition().getX().getReal()).append(comma).
  681.                                   append(getPosition().getY().getReal()).append(comma).
  682.                                   append(getPosition().getZ().getReal()).append("), V(").
  683.                                   append(getVelocity().getX().getReal()).append(comma).
  684.                                   append(getVelocity().getY().getReal()).append(comma).
  685.                                   append(getVelocity().getZ().getReal()).append("), A(").
  686.                                   append(getAcceleration().getX().getReal()).append(comma).
  687.                                   append(getAcceleration().getY().getReal()).append(comma).
  688.                                   append(getAcceleration().getZ().getReal()).append(")}").toString();
  689.     }

  690. }