GroundPointing.java

  1. /* Copyright 2002-2013 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 org.apache.commons.math3.geometry.euclidean.threed.Rotation;
  19. import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
  20. import org.orekit.errors.OrekitException;
  21. import org.orekit.errors.OrekitMessages;
  22. import org.orekit.frames.Frame;
  23. import org.orekit.time.AbsoluteDate;
  24. import org.orekit.utils.AngularCoordinates;
  25. import org.orekit.utils.PVCoordinates;
  26. import org.orekit.utils.PVCoordinatesProvider;


  27. /**
  28.  * Base class for ground pointing attitude providers.
  29.  *
  30.  * <p>This class is a basic model for different kind of ground pointing
  31.  * attitude providers, such as : body center pointing, nadir pointing,
  32.  * target pointing, etc...
  33.  * </p>
  34.  * <p>
  35.  * The object <code>GroundPointing</code> is guaranteed to be immutable.
  36.  * </p>
  37.  * @see     AttitudeProvider
  38.  * @author V&eacute;ronique Pommier-Maurussane
  39.  */
  40. public abstract class GroundPointing implements AttitudeProvider {

  41.     /** Serializable UID. */
  42.     private static final long serialVersionUID = -1459257023765594793L;

  43.     /** Body frame. */
  44.     private final Frame bodyFrame;

  45.     /** Default constructor.
  46.      * Build a new instance with arbitrary default elements.
  47.      * @param bodyFrame the frame that rotates with the body
  48.      */
  49.     protected GroundPointing(final Frame bodyFrame) {
  50.         this.bodyFrame = bodyFrame;
  51.     }

  52.     /** Get the body frame.
  53.      * @return body frame
  54.      */
  55.     public Frame getBodyFrame() {
  56.         return bodyFrame;
  57.     }

  58.     /** Compute the target point in specified frame.
  59.      * @param pvProv provider for PV coordinates
  60.      * @param date date at which target point is requested
  61.      * @param frame frame in which observed ground point should be provided
  62.      * @return observed ground point position in specified frame
  63.      * @throws OrekitException if some specific error occurs,
  64.      * such as no target reached
  65.      */
  66.     protected abstract Vector3D getTargetPoint(final PVCoordinatesProvider pvProv,
  67.                                                final AbsoluteDate date, final Frame frame)
  68.         throws OrekitException;

  69.     /** Compute the target point position/velocity in specified frame.
  70.      * <p>The default implementation use a simple two points finite differences scheme,
  71.      * it may be replaced by more accurate models in specialized implementations.</p>
  72.      * @param pvProv provider for PV coordinates
  73.      * @param date date at which target point is requested
  74.      * @param frame frame in which observed ground point should be provided
  75.      * @return observed ground point position/velocity in specified frame
  76.      * @throws OrekitException if some specific error occurs,
  77.      * such as no target reached
  78.      */
  79.     protected PVCoordinates getTargetPV(final PVCoordinatesProvider pvProv,
  80.                                         final AbsoluteDate date, final Frame frame)
  81.         throws OrekitException {

  82.         // target point position in same frame as initial pv
  83.         final Vector3D intersectionP = getTargetPoint(pvProv, date, frame);

  84.         // velocity of target point due to satellite and target motions
  85.         final double h  = 0.1;
  86.         final double scale = 1.0 / (2 * h);
  87.         final Vector3D intersectionM1h = getTargetPoint(pvProv, date.shiftedBy(-h), frame);
  88.         final Vector3D intersectionP1h = getTargetPoint(pvProv, date.shiftedBy( h), frame);
  89.         final Vector3D intersectionV   = new Vector3D(scale, intersectionP1h, -scale, intersectionM1h);

  90.         return new PVCoordinates(intersectionP, intersectionV);

  91.     }


  92.     /** {@inheritDoc} */
  93.     public Attitude getAttitude(final PVCoordinatesProvider pvProv, final AbsoluteDate date,
  94.                                 final Frame frame)
  95.         throws OrekitException {

  96.         // Construction of the satellite-target position/velocity vector at t-h, t and t+h
  97.         final double h = 0.1;

  98.         final AbsoluteDate dateM1H = date.shiftedBy(-h);
  99.         final PVCoordinates pvM1H  = pvProv.getPVCoordinates(dateM1H, frame);
  100.         final Vector3D deltaPM1h   = getTargetPoint(pvProv, dateM1H, frame).subtract(pvM1H.getPosition());

  101.         final PVCoordinates pv0    = pvProv.getPVCoordinates(date, frame);
  102.         final Vector3D deltaP0     = getTargetPoint(pvProv, date, frame).subtract(pv0.getPosition());

  103.         final AbsoluteDate dateP1H = date.shiftedBy(h);
  104.         final PVCoordinates pvP1H  = pvProv.getPVCoordinates(dateP1H, frame);
  105.         final Vector3D deltaPP1h   = getTargetPoint(pvProv, dateP1H, frame).subtract(pvP1H.getPosition());

  106.         // New orekit exception if null position.
  107.         if (deltaP0.equals(Vector3D.ZERO)) {
  108.             throw new OrekitException(OrekitMessages.SATELLITE_COLLIDED_WITH_TARGET);
  109.         }

  110.         // Attitude rotation:
  111.         // line of sight -> z satellite axis,
  112.         // satellite velocity -> x satellite axis.
  113.         final Rotation rot    = new Rotation(deltaP0,   pv0.getVelocity(),   Vector3D.PLUS_K, Vector3D.PLUS_I);

  114.         // Attitude spin
  115.         final Rotation rotM1h = new Rotation(deltaPM1h, pvM1H.getVelocity(), Vector3D.PLUS_K, Vector3D.PLUS_I);
  116.         final Rotation rotP1h = new Rotation(deltaPP1h, pvP1H.getVelocity(), Vector3D.PLUS_K, Vector3D.PLUS_I);
  117.         final Vector3D spin   = AngularCoordinates.estimateRate(rotM1h, rotP1h, 2 * h);

  118.         return new Attitude(date, frame, rot, spin);

  119.     }

  120. }