NadirPointing.java

  1. /* Copyright 2002-2018 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.attitudes;

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. import org.hipparchus.RealFieldElement;
  21. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  22. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  23. import org.orekit.bodies.BodyShape;
  24. import org.orekit.bodies.FieldGeodeticPoint;
  25. import org.orekit.bodies.GeodeticPoint;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.frames.FieldTransform;
  28. import org.orekit.frames.Frame;
  29. import org.orekit.frames.Transform;
  30. import org.orekit.time.AbsoluteDate;
  31. import org.orekit.time.FieldAbsoluteDate;
  32. import org.orekit.utils.CartesianDerivativesFilter;
  33. import org.orekit.utils.FieldPVCoordinatesProvider;
  34. import org.orekit.utils.PVCoordinatesProvider;
  35. import org.orekit.utils.TimeStampedFieldPVCoordinates;
  36. import org.orekit.utils.TimeStampedPVCoordinates;

  37. /**
  38.  * This class handles nadir pointing attitude provider.

  39.  * <p>
  40.  * This class represents the attitude provider where the satellite z axis is
  41.  * pointing to the vertical of the ground point under satellite.</p>
  42.  * <p>
  43.  * The object <code>NadirPointing</code> is guaranteed to be immutable.
  44.  * </p>
  45.  * @see     GroundPointing
  46.  * @author V&eacute;ronique Pommier-Maurussane
  47.  */
  48. public class NadirPointing extends GroundPointing {

  49.     /** Serializable UID. */
  50.     private static final long serialVersionUID = 20150529L;

  51.     /** Body shape.  */
  52.     private final BodyShape shape;

  53.     /** Creates new instance.
  54.      * @param inertialFrame frame in which orbital velocities are computed
  55.      * @param shape Body shape
  56.      * @exception OrekitException if the frame specified is not a pseudo-inertial frame
  57.      * @since 7.1
  58.      */
  59.     public NadirPointing(final Frame inertialFrame, final BodyShape shape)
  60.         throws OrekitException {
  61.         // Call constructor of superclass
  62.         super(inertialFrame, shape.getBodyFrame());
  63.         this.shape = shape;
  64.     }

  65.     /** {@inheritDoc} */
  66.     public TimeStampedPVCoordinates getTargetPV(final PVCoordinatesProvider pvProv,
  67.                                                 final AbsoluteDate date, final Frame frame)
  68.         throws OrekitException {

  69.         // transform from specified reference frame to body frame
  70.         final Transform refToBody = frame.getTransformTo(shape.getBodyFrame(), date);

  71.         // sample intersection points in current date neighborhood
  72.         final double h  = 0.01;
  73.         final List<TimeStampedPVCoordinates> sample = new ArrayList<>();
  74.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-2 * h), frame), refToBody.shiftedBy(-2 * h)));
  75.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-h),     frame), refToBody.shiftedBy(-h)));
  76.         sample.add(nadirRef(pvProv.getPVCoordinates(date,                   frame), refToBody));
  77.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+h),     frame), refToBody.shiftedBy(+h)));
  78.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+2 * h), frame), refToBody.shiftedBy(+2 * h)));

  79.         // use interpolation to compute properly the time-derivatives
  80.         return TimeStampedPVCoordinates.interpolate(date, CartesianDerivativesFilter.USE_P, sample);

  81.     }

  82.     /** {@inheritDoc} */
  83.     public <T extends RealFieldElement<T>> TimeStampedFieldPVCoordinates<T> getTargetPV(final FieldPVCoordinatesProvider<T> pvProv,
  84.                                                                                         final FieldAbsoluteDate<T> date,
  85.                                                                                         final Frame frame)
  86.         throws OrekitException {

  87.         // transform from specified reference frame to body frame
  88.         final FieldTransform<T> refToBody = frame.getTransformTo(shape.getBodyFrame(), date);

  89.         // sample intersection points in current date neighborhood
  90.         final double h  = 0.01;
  91.         final List<TimeStampedFieldPVCoordinates<T>> sample = new ArrayList<>();
  92.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-2 * h), frame), refToBody.shiftedBy(-2 * h)));
  93.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-h),     frame), refToBody.shiftedBy(-h)));
  94.         sample.add(nadirRef(pvProv.getPVCoordinates(date,                   frame), refToBody));
  95.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+h),     frame), refToBody.shiftedBy(+h)));
  96.         sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+2 * h), frame), refToBody.shiftedBy(+2 * h)));

  97.         // use interpolation to compute properly the time-derivatives
  98.         return TimeStampedFieldPVCoordinates.interpolate(date, CartesianDerivativesFilter.USE_P, sample);

  99.     }

  100.     /** Compute ground point in nadir direction, in reference frame.
  101.      * @param scRef spacecraft coordinates in reference frame
  102.      * @param refToBody transform from reference frame to body frame
  103.      * @return intersection point in body frame (only the position is set!)
  104.      * @exception OrekitException if line of sight does not intersect body
  105.      */
  106.     private TimeStampedPVCoordinates nadirRef(final TimeStampedPVCoordinates scRef, final Transform refToBody)
  107.         throws OrekitException {

  108.         final Vector3D satInBodyFrame = refToBody.transformPosition(scRef.getPosition());

  109.         // satellite position in geodetic coordinates
  110.         final GeodeticPoint gpSat = shape.transform(satInBodyFrame, getBodyFrame(), scRef.getDate());

  111.         // nadir position in geodetic coordinates
  112.         final GeodeticPoint gpNadir = new GeodeticPoint(gpSat.getLatitude(), gpSat.getLongitude(), 0.0);

  113.         // nadir point position in body frame
  114.         final Vector3D pNadirBody = shape.transform(gpNadir);

  115.         // nadir point position in reference frame
  116.         final Vector3D pNadirRef = refToBody.getInverse().transformPosition(pNadirBody);

  117.         return new TimeStampedPVCoordinates(scRef.getDate(), pNadirRef, Vector3D.ZERO, Vector3D.ZERO);

  118.     }

  119.     /** Compute ground point in nadir direction, in reference frame.
  120.      * @param scRef spacecraft coordinates in reference frame
  121.      * @param refToBody transform from reference frame to body frame
  122.      * @param <T> type of the field elements
  123.      * @return intersection point in body frame (only the position is set!)
  124.      * @exception OrekitException if line of sight does not intersect body
  125.      * @since 9.0
  126.      */
  127.     private <T extends RealFieldElement<T>> TimeStampedFieldPVCoordinates<T> nadirRef(final TimeStampedFieldPVCoordinates<T> scRef,
  128.                                                                                       final FieldTransform<T> refToBody)
  129.         throws OrekitException {

  130.         final FieldVector3D<T> satInBodyFrame = refToBody.transformPosition(scRef.getPosition());

  131.         // satellite position in geodetic coordinates
  132.         final FieldGeodeticPoint<T> gpSat = shape.transform(satInBodyFrame, getBodyFrame(), scRef.getDate());

  133.         // nadir position in geodetic coordinates
  134.         final FieldGeodeticPoint<T> gpNadir = new FieldGeodeticPoint<>(gpSat.getLatitude(), gpSat.getLongitude(),
  135.                                                                        gpSat.getAltitude().getField().getZero());

  136.         // nadir point position in body frame
  137.         final FieldVector3D<T> pNadirBody = shape.transform(gpNadir);

  138.         // nadir point position in reference frame
  139.         final FieldVector3D<T> pNadirRef = refToBody.getInverse().transformPosition(pNadirBody);

  140.         final FieldVector3D<T> zero = FieldVector3D.getZero(gpSat.getAltitude().getField());
  141.         return new TimeStampedFieldPVCoordinates<>(scRef.getDate(), pNadirRef, zero, zero);

  142.     }

  143. }