PredefinedTarget.java
/* Copyright 2002-2024 Luc Maisonobe
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.attitudes;
import org.hipparchus.CalculusFieldElement;
import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
import org.hipparchus.analysis.differentiation.UnivariateDerivative2Field;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.bodies.FieldGeodeticPoint;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.frames.FieldStaticTransform;
import org.orekit.frames.Frame;
import org.orekit.frames.StaticTransform;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.utils.ExtendedPositionProvider;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.TimeStampedFieldPVCoordinates;
import org.orekit.utils.TimeStampedPVCoordinates;
/**
* Predefined targets for {@link AlignedAndConstrained}.
* @author Luc Maisonobe
* @since 12.2
*/
public enum PredefinedTarget implements TargetProvider
{
/** Sun direction. */
SUN {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
return new PVCoordinates(pv, sun.getPVCoordinates(pv.getDate(), frame)).
toUnivariateDerivative2Vector().
normalize();
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
return sun.getPosition(pv.getDate(), frame).subtract(pv.getPosition()).normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return sun.getPosition(pv.getDate(), frame).subtract(pv.getPosition()).normalize();
}
},
/** Earth direction (assumes the frame is Earth centered). */
EARTH {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
return pv.toUnivariateDerivative2Vector().negate().normalize();
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
return pv.getPosition().negate().normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<FieldUnivariateDerivative2<T>> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return pv.toUnivariateDerivative2Vector().negate().normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return pv.getPosition().negate().normalize();
}
},
/** Nadir. */
NADIR {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
final FieldStaticTransform<UnivariateDerivative2> inert2Earth = inert2Earth(earth, pv.getDate(), frame);
final FieldGeodeticPoint<UnivariateDerivative2> gp = toGeodeticPoint(earth, pv, inert2Earth);
return inert2Earth.getStaticInverse().transformVector(gp.getNadir());
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
final StaticTransform inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
final GeodeticPoint geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
earth.getBodyFrame(), pv.getDate());
return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNadir());
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
final FieldStaticTransform<T> inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
final FieldGeodeticPoint<T> geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
earth.getBodyFrame(), pv.getDate());
return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNadir());
}
},
/** North direction. */
NORTH {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
final FieldStaticTransform<UnivariateDerivative2> inert2Earth = inert2Earth(earth, pv.getDate(), frame);
final FieldGeodeticPoint<UnivariateDerivative2> gp = toGeodeticPoint(earth, pv, inert2Earth);
return inert2Earth.getStaticInverse().transformVector(gp.getNorth());
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
final StaticTransform inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
final GeodeticPoint geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
earth.getBodyFrame(), pv.getDate());
return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNorth());
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
final FieldStaticTransform<T> inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
final FieldGeodeticPoint<T> geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
earth.getBodyFrame(), pv.getDate());
return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNorth());
}
},
/** East direction. */
EAST {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
final FieldStaticTransform<UnivariateDerivative2> inert2Earth = inert2Earth(earth, pv.getDate(), frame);
final FieldGeodeticPoint<UnivariateDerivative2> gp = toGeodeticPoint(earth, pv, inert2Earth);
return inert2Earth.getStaticInverse().transformVector(gp.getEast());
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
final StaticTransform inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
final GeodeticPoint geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
earth.getBodyFrame(), pv.getDate());
return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getEast());
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
final FieldStaticTransform<T> inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
final FieldGeodeticPoint<T> geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
earth.getBodyFrame(), pv.getDate());
return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getEast());
}
},
/** Satellite velocity. */
VELOCITY {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
return pv.toUnivariateDerivative2PV().getVelocity().normalize();
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
return pv.getVelocity().normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<FieldUnivariateDerivative2<T>> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return pv.toUnivariateDerivative2PV().getVelocity().normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return pv.getVelocity().normalize();
}
},
/** Satellite orbital momentum. */
MOMENTUM {
/** {@inheritDoc} */
@Override
public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final Frame frame) {
return pv.toUnivariateDerivative2PV().getMomentum().normalize();
}
/** {@inheritDoc} */
@Override
public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv, final Frame frame) {
return pv.getMomentum().normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<FieldUnivariateDerivative2<T>> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return pv.toUnivariateDerivative2PV().getMomentum().normalize();
}
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
final OneAxisEllipsoid earth,
final TimeStampedFieldPVCoordinates<T> pv,
final Frame frame) {
return pv.getMomentum().normalize();
}
};
/** Get transform from inertial frame to Earth frame.
* @param earth Earth model
* @param date date
* @param frame inertial frame
* @return geodetic point with derivatives
*/
private static FieldStaticTransform<UnivariateDerivative2> inert2Earth(final OneAxisEllipsoid earth,
final AbsoluteDate date,
final Frame frame) {
final FieldAbsoluteDate<UnivariateDerivative2> dateU2 =
new FieldAbsoluteDate<>(UnivariateDerivative2Field.getInstance(), date).
shiftedBy(new UnivariateDerivative2(0.0, 1.0, 0.0));
return frame.getStaticTransformTo(earth.getBodyFrame(), dateU2);
}
/** Convert to geodetic point with derivatives.
* @param earth Earth model
* @param pv spacecraft position and velocity
* @param inert2Earth transform from inertial frame to Earth frame
* @return geodetic point with derivatives
*/
private static FieldGeodeticPoint<UnivariateDerivative2> toGeodeticPoint(final OneAxisEllipsoid earth,
final TimeStampedPVCoordinates pv,
final FieldStaticTransform<UnivariateDerivative2> inert2Earth) {
return earth.transform(inert2Earth.transformPosition(pv.toUnivariateDerivative2Vector()),
earth.getBodyFrame(), inert2Earth.getFieldDate());
}
}