AbsolutePVCoordinates.java

  1. /* Copyright 2002-2025 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 org.hipparchus.analysis.differentiation.Derivative;
  19. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  20. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  21. import org.orekit.errors.OrekitException;
  22. import org.orekit.errors.OrekitIllegalArgumentException;
  23. import org.orekit.errors.OrekitMessages;
  24. import org.orekit.frames.Frame;
  25. import org.orekit.frames.StaticTransform;
  26. import org.orekit.frames.Transform;
  27. import org.orekit.time.AbsoluteDate;
  28. import org.orekit.time.TimeOffset;
  29. import org.orekit.time.TimeStamped;

  30. /** Position - Velocity - Acceleration linked to a date and a frame.
  31.  */
  32. public class AbsolutePVCoordinates extends TimeStampedPVCoordinates implements TimeStamped, PVCoordinatesProvider {

  33.     /** Frame in which are defined the coordinates. */
  34.     private final Frame frame;

  35.     /** Build from position, velocity, acceleration.
  36.      * @param frame the frame in which the coordinates are defined
  37.      * @param date coordinates date
  38.      * @param position the position vector (m)
  39.      * @param velocity the velocity vector (m/s)
  40.      * @param acceleration the acceleration vector (m/sÂý)
  41.      */
  42.     public AbsolutePVCoordinates(final Frame frame, final AbsoluteDate date,
  43.                                  final Vector3D position, final Vector3D velocity, final Vector3D acceleration) {
  44.         super(date, position, velocity, acceleration);
  45.         this.frame = frame;
  46.     }

  47.     /** Build from position and velocity. Acceleration is set to zero.
  48.      * @param frame the frame in which the coordinates are defined
  49.      * @param date coordinates date
  50.      * @param position the position vector (m)
  51.      * @param velocity the velocity vector (m/s)
  52.      */
  53.     public AbsolutePVCoordinates(final Frame frame, final AbsoluteDate date,
  54.                                  final Vector3D position,
  55.                                  final Vector3D velocity) {
  56.         this(frame, date, position, velocity, Vector3D.ZERO);
  57.     }

  58.     /** Build from frame, date and PVA coordinates.
  59.      * @param frame the frame in which the coordinates are defined
  60.      * @param date date of the coordinates
  61.      * @param pva TimeStampedPVCoordinates
  62.      */
  63.     public AbsolutePVCoordinates(final Frame frame, final AbsoluteDate date, final PVCoordinates pva) {
  64.         super(date, pva);
  65.         this.frame = frame;
  66.     }

  67.     /** Build from frame and TimeStampedPVCoordinates.
  68.      * @param frame the frame in which the coordinates are defined
  69.      * @param pva TimeStampedPVCoordinates
  70.      */
  71.     public AbsolutePVCoordinates(final Frame frame, final TimeStampedPVCoordinates pva) {
  72.         super(pva.getDate(), pva);
  73.         this.frame = frame;
  74.     }

  75.     /** Multiplicative constructor
  76.      * <p>Build a AbsolutePVCoordinates from another one and a scale factor.</p>
  77.      * <p>The TimeStampedPVCoordinates built will be a * AbsPva</p>
  78.      * @param date date of the built coordinates
  79.      * @param a scale factor
  80.      * @param AbsPva base (unscaled) AbsolutePVCoordinates
  81.      */
  82.     public AbsolutePVCoordinates(final AbsoluteDate date,
  83.                                  final double a, final AbsolutePVCoordinates AbsPva) {
  84.         super(date, a, AbsPva);
  85.         this.frame = AbsPva.frame;
  86.     }

  87.     /** Subtractive constructor
  88.      * <p>Build a relative AbsolutePVCoordinates from a start and an end position.</p>
  89.      * <p>The AbsolutePVCoordinates built will be end - start.</p>
  90.      * <p>In case start and end use two different pseudo-inertial frames,
  91.      * the new AbsolutePVCoordinates arbitrarily be defined in the start frame. </p>
  92.      * @param date date of the built coordinates
  93.      * @param start Starting AbsolutePVCoordinates
  94.      * @param end ending AbsolutePVCoordinates
  95.      */
  96.     public AbsolutePVCoordinates(final AbsoluteDate date,
  97.                                  final AbsolutePVCoordinates start, final AbsolutePVCoordinates end) {
  98.         super(date, start, end);
  99.         ensureIdenticalFrames(start, end);
  100.         this.frame = start.frame;
  101.     }

  102.     /** Linear constructor
  103.      * <p>Build a AbsolutePVCoordinates from two other ones and corresponding scale factors.</p>
  104.      * <p>The AbsolutePVCoordinates built will be a1 * u1 + a2 * u2</p>
  105.      * <p>In case the AbsolutePVCoordinates use different pseudo-inertial frames,
  106.      * the new AbsolutePVCoordinates arbitrarily be defined in the first frame. </p>
  107.      * @param date date of the built coordinates
  108.      * @param a1 first scale factor
  109.      * @param absPv1 first base (unscaled) AbsolutePVCoordinates
  110.      * @param a2 second scale factor
  111.      * @param absPv2 second base (unscaled) AbsolutePVCoordinates
  112.      */
  113.     public AbsolutePVCoordinates(final AbsoluteDate date,
  114.                                  final double a1, final AbsolutePVCoordinates absPv1,
  115.                                  final double a2, final AbsolutePVCoordinates absPv2) {
  116.         super(date, a1, absPv1.getPVCoordinates(), a2, absPv2.getPVCoordinates());
  117.         ensureIdenticalFrames(absPv1, absPv2);
  118.         this.frame = absPv1.getFrame();
  119.     }

  120.     /** Linear constructor
  121.      * <p>Build a AbsolutePVCoordinates from three other ones and corresponding scale factors.</p>
  122.      * <p>The AbsolutePVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
  123.      * <p>In case the AbsolutePVCoordinates use different pseudo-inertial frames,
  124.      * the new AbsolutePVCoordinates arbitrarily be defined in the first frame. </p>
  125.      * @param date date of the built coordinates
  126.      * @param a1 first scale factor
  127.      * @param absPv1 first base (unscaled) AbsolutePVCoordinates
  128.      * @param a2 second scale factor
  129.      * @param absPv2 second base (unscaled) AbsolutePVCoordinates
  130.      * @param a3 third scale factor
  131.      * @param absPv3 third base (unscaled) AbsolutePVCoordinates
  132.      */
  133.     public AbsolutePVCoordinates(final AbsoluteDate date,
  134.                                  final double a1, final AbsolutePVCoordinates absPv1,
  135.                                  final double a2, final AbsolutePVCoordinates absPv2,
  136.                                  final double a3, final AbsolutePVCoordinates absPv3) {
  137.         super(date, a1, absPv1.getPVCoordinates(), a2, absPv2.getPVCoordinates(),
  138.                 a3, absPv3.getPVCoordinates());
  139.         ensureIdenticalFrames(absPv1, absPv2);
  140.         ensureIdenticalFrames(absPv1, absPv3);
  141.         this.frame = absPv1.getFrame();
  142.     }

  143.     /** Linear constructor
  144.      * <p>Build a AbsolutePVCoordinates from four other ones and corresponding scale factors.</p>
  145.      * <p>The AbsolutePVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
  146.      * <p>In case the AbsolutePVCoordinates use different pseudo-inertial frames,
  147.      * the new AbsolutePVCoordinates arbitrarily be defined in the first frame. </p>
  148.      * @param date date of the built coordinates
  149.      * @param a1 first scale factor
  150.      * @param absPv1 first base (unscaled) AbsolutePVCoordinates
  151.      * @param a2 second scale factor
  152.      * @param absPv2 second base (unscaled) AbsolutePVCoordinates
  153.      * @param a3 third scale factor
  154.      * @param absPv3 third base (unscaled) AbsolutePVCoordinates
  155.      * @param a4 fourth scale factor
  156.      * @param absPv4 fourth base (unscaled) AbsolutePVCoordinates
  157.      */
  158.     public AbsolutePVCoordinates(final AbsoluteDate date,
  159.                                  final double a1, final AbsolutePVCoordinates absPv1,
  160.                                  final double a2, final AbsolutePVCoordinates absPv2,
  161.                                  final double a3, final AbsolutePVCoordinates absPv3,
  162.                                  final double a4, final AbsolutePVCoordinates absPv4) {
  163.         super(date, a1, absPv1.getPVCoordinates(), a2, absPv2.getPVCoordinates(),
  164.                 a3, absPv3.getPVCoordinates(), a4, absPv4.getPVCoordinates());
  165.         ensureIdenticalFrames(absPv1, absPv2);
  166.         ensureIdenticalFrames(absPv1, absPv3);
  167.         ensureIdenticalFrames(absPv1, absPv4);
  168.         this.frame = absPv1.getFrame();
  169.     }

  170.     /** Builds a AbsolutePVCoordinates triplet from  a {@link FieldVector3D}&lt;{@link Derivative}&gt;.
  171.      * <p>
  172.      * The vector components must have time as their only derivation parameter and
  173.      * have consistent derivation orders.
  174.      * </p>
  175.      * @param frame the frame in which the parameters are defined
  176.      * @param date date of the built coordinates
  177.      * @param p vector with time-derivatives embedded within the coordinates
  178.      * @param <U> type of the derivative
  179.      */
  180.     public <U extends Derivative<U>> AbsolutePVCoordinates(final Frame frame, final AbsoluteDate date,
  181.                                                            final FieldVector3D<U> p) {
  182.         super(date, p);
  183.         this.frame = frame;
  184.     }

  185.     /** Ensure that the frames from two AbsolutePVCoordinates are identical.
  186.      * @param absPv1 first AbsolutePVCoordinates
  187.      * @param absPv2 first AbsolutePVCoordinates
  188.      * @throws OrekitIllegalArgumentException if frames are different
  189.      */
  190.     private static void ensureIdenticalFrames(final AbsolutePVCoordinates absPv1, final AbsolutePVCoordinates absPv2)
  191.         throws OrekitIllegalArgumentException {
  192.         if (!absPv1.frame.equals(absPv2.frame)) {
  193.             throw new OrekitIllegalArgumentException(OrekitMessages.INCOMPATIBLE_FRAMES,
  194.                                                      absPv1.frame.getName(), absPv2.frame.getName());
  195.         }
  196.     }

  197.     /** Get a time-shifted state.
  198.      * <p>
  199.      * The state can be slightly shifted to close dates. This shift is based on
  200.      * a simple Taylor expansion. It is <em>not</em> intended as a replacement for
  201.      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
  202.      * for either small time shifts or coarse accuracy.
  203.      * </p>
  204.      * @param dt time shift in seconds
  205.      * @return a new state, shifted with respect to the instance (which is immutable)
  206.      */
  207.     public AbsolutePVCoordinates shiftedBy(final double dt) {
  208.         final TimeStampedPVCoordinates spv = super.shiftedBy(dt);
  209.         return new AbsolutePVCoordinates(frame, spv);
  210.     }

  211.     /** Get a time-shifted state.
  212.      * <p>
  213.      * The state can be slightly shifted to close dates. This shift is based on
  214.      * a simple Taylor expansion. It is <em>not</em> intended as a replacement for
  215.      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
  216.      * for either small time shifts or coarse accuracy.
  217.      * </p>
  218.      * @param dt time shift in seconds
  219.      * @return a new state, shifted with respect to the instance (which is immutable)
  220.      * @since 13.0
  221.      */
  222.     public AbsolutePVCoordinates shiftedBy(final TimeOffset dt) {
  223.         final TimeStampedPVCoordinates spv = super.shiftedBy(dt);
  224.         return new AbsolutePVCoordinates(frame, spv);
  225.     }

  226.     /** Create a local provider using simply Taylor expansion through {@link #shiftedBy(double)}.
  227.      * <p>
  228.      * The time evolution is based on a simple Taylor expansion. It is <em>not</em> intended as a
  229.      * replacement for proper orbit propagation (it is not even Keplerian!) but should be sufficient
  230.      * for either small time shifts or coarse accuracy.
  231.      * </p>
  232.      * @return provider based on Taylor expansion, for small time shifts around instance date
  233.      */
  234.     public PVCoordinatesProvider toTaylorProvider() {
  235.         return new PVCoordinatesProvider() {
  236.             /** {@inheritDoc} */
  237.             public Vector3D getPosition(final AbsoluteDate d,  final Frame f) {
  238.                 final TimeStampedPVCoordinates shifted   = shiftedBy(d.durationFrom(getDate()));
  239.                 final StaticTransform          transform = frame.getStaticTransformTo(f, d);
  240.                 return transform.transformPosition(shifted.getPosition());
  241.             }
  242.             /** {@inheritDoc} */
  243.             public TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate d,  final Frame f) {
  244.                 final TimeStampedPVCoordinates shifted   = shiftedBy(d.durationFrom(getDate()));
  245.                 final Transform                transform = frame.getTransformTo(f, d);
  246.                 return transform.transformPVCoordinates(shifted);
  247.             }
  248.         };
  249.     }

  250.     /** Get the frame in which the coordinates are defined.
  251.      * @return frame in which the coordinates are defined
  252.      */
  253.     public Frame getFrame() {
  254.         return frame;
  255.     }

  256.     /** Get the TimeStampedPVCoordinates.
  257.      * @return TimeStampedPVCoordinates
  258.      */
  259.     public TimeStampedPVCoordinates getPVCoordinates() {
  260.         return this;
  261.     }

  262.     /** Get the position in a specified frame.
  263.      * @param outputFrame frame in which the position coordinates shall be computed
  264.      * @return position
  265.      * @see #getPVCoordinates(Frame)
  266.      * @since 12.0
  267.      */
  268.     public Vector3D getPosition(final Frame outputFrame) {
  269.         // If output frame requested is the same as definition frame,
  270.         // Position vector is returned directly
  271.         if (outputFrame == frame) {
  272.             return getPosition();
  273.         }

  274.         // Else, position vector is transformed to output frame
  275.         final StaticTransform t = frame.getStaticTransformTo(outputFrame, getDate());
  276.         return t.transformPosition(getPosition());
  277.     }

  278.     /** Get the TimeStampedPVCoordinates in a specified frame.
  279.      * @param outputFrame frame in which the position/velocity coordinates shall be computed
  280.      * @return TimeStampedPVCoordinates
  281.      * @exception OrekitException if transformation between frames cannot be computed
  282.      * @see #getPVCoordinates()
  283.      */
  284.     public TimeStampedPVCoordinates getPVCoordinates(final Frame outputFrame) {
  285.         // If output frame requested is the same as definition frame,
  286.         // PV coordinates are returned directly
  287.         if (outputFrame == frame) {
  288.             return getPVCoordinates();
  289.         }

  290.         // Else, PV coordinates are transformed to output frame
  291.         final Transform t = frame.getTransformTo(outputFrame, getDate());
  292.         return t.transformPVCoordinates(getPVCoordinates());
  293.     }

  294.     @Override
  295.     public TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate otherDate, final Frame outputFrame) {
  296.         return shiftedBy(otherDate.durationFrom(getDate())).getPVCoordinates(outputFrame);
  297.     }

  298. }