All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.orekit.attitudes.NadirPointing Maven / Gradle / Ivy

Go to download

OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library. It provides basic elements (orbits, dates, attitude, frames ...) and various algorithms to handle them (conversions, analytical and numerical propagation, pointing ...).

There is a newer version: 12.2
Show newest version
/* Copyright 2002-2024 CS GROUP
 * 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 java.util.ArrayList;
import java.util.List;

import org.hipparchus.CalculusFieldElement;
import org.hipparchus.Field;
import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2Field;
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.BodyShape;
import org.orekit.bodies.FieldGeodeticPoint;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.frames.FieldStaticTransform;
import org.orekit.frames.FieldTransform;
import org.orekit.frames.Frame;
import org.orekit.frames.StaticTransform;
import org.orekit.frames.Transform;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.time.FieldTimeInterpolator;
import org.orekit.time.TimeInterpolator;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.FieldPVCoordinatesProvider;
import org.orekit.utils.FieldPVCoordinates;
import org.orekit.utils.PVCoordinatesProvider;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.TimeStampedFieldPVCoordinates;
import org.orekit.utils.TimeStampedFieldPVCoordinatesHermiteInterpolator;
import org.orekit.utils.TimeStampedPVCoordinates;
import org.orekit.utils.TimeStampedPVCoordinatesHermiteInterpolator;

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

 * 

* This class represents the attitude provider where the satellite z axis is * pointing to the vertical of the ground point under satellite.

*

* The object NadirPointing is guaranteed to be immutable. *

* @see GroundPointing * @author Véronique Pommier-Maurussane */ public class NadirPointing extends GroundPointing { /** Body shape. */ private final BodyShape shape; /** Creates new instance. * @param inertialFrame frame in which orbital velocities are computed * @param shape Body shape * @since 7.1 */ public NadirPointing(final Frame inertialFrame, final BodyShape shape) { // Call constructor of superclass super(inertialFrame, shape.getBodyFrame()); this.shape = shape; } /** {@inheritDoc} */ @Override public TimeStampedPVCoordinates getTargetPV(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) { final TimeStampedPVCoordinates pvCoordinatesInRef = pvProv.getPVCoordinates(date, frame); if (pvCoordinatesInRef.getAcceleration().equals(Vector3D.ZERO)) { // let us assume that there is no proper acceleration available, so need to use interpolation for derivatives return getTargetPVViaInterpolation(pvProv, date, frame); } else { // use automatic differentiation // build time dependent transform final UnivariateDerivative2Field ud2Field = UnivariateDerivative2Field.getInstance(); final UnivariateDerivative2 dt = new UnivariateDerivative2(0., 1., 0.); final FieldAbsoluteDate ud2Date = new FieldAbsoluteDate<>(ud2Field, date).shiftedBy(dt); final FieldStaticTransform refToBody = frame.getStaticTransformTo(shape.getBodyFrame(), ud2Date); final FieldVector3D positionInRefFrame = pvCoordinatesInRef.toUnivariateDerivative2Vector(); final FieldVector3D positionInBodyFrame = refToBody.transformPosition(positionInRefFrame); // satellite position in geodetic coordinates final FieldGeodeticPoint gpSat = shape.transform(positionInBodyFrame, getBodyFrame(), ud2Date); // nadir position in geodetic coordinates final FieldGeodeticPoint gpNadir = new FieldGeodeticPoint<>(gpSat.getLatitude(), gpSat.getLongitude(), ud2Field.getZero()); // nadir point position in body frame final FieldVector3D positionNadirInBodyFrame = shape.transform(gpNadir); // nadir point position in reference frame final FieldStaticTransform bodyToRef = refToBody.getInverse(); final FieldVector3D positionNadirInRefFrame = bodyToRef.transformPosition(positionNadirInBodyFrame); // put derivatives into proper object final Vector3D velocity = new Vector3D(positionNadirInRefFrame.getX().getFirstDerivative(), positionNadirInRefFrame.getY().getFirstDerivative(), positionNadirInRefFrame.getZ().getFirstDerivative()); final Vector3D acceleration = new Vector3D(positionNadirInRefFrame.getX().getSecondDerivative(), positionNadirInRefFrame.getY().getSecondDerivative(), positionNadirInRefFrame.getZ().getSecondDerivative()); return new TimeStampedPVCoordinates(date, positionNadirInRefFrame.toVector3D(), velocity, acceleration); } } /** * Compute target position-velocity-acceleration vector via interpolation. * @param pvProv PV provider * @param date date * @param frame frame * @return target position-velocity-acceleration */ public TimeStampedPVCoordinates getTargetPVViaInterpolation(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) { // transform from specified reference frame to body frame final Transform refToBody = frame.getTransformTo(shape.getBodyFrame(), date); // sample intersection points in current date neighborhood final double h = 0.01; final List sample = new ArrayList<>(); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-2 * h), frame), refToBody.staticShiftedBy(-2 * h))); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-h), frame), refToBody.staticShiftedBy(-h))); sample.add(nadirRef(pvProv.getPVCoordinates(date, frame), refToBody)); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+h), frame), refToBody.staticShiftedBy(+h))); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+2 * h), frame), refToBody.staticShiftedBy(+2 * h))); // create interpolator final TimeInterpolator interpolator = new TimeStampedPVCoordinatesHermiteInterpolator(sample.size(), CartesianDerivativesFilter.USE_P); // use interpolation to compute properly the time-derivatives return interpolator.interpolate(date, sample); } /** {@inheritDoc} */ @Override protected Vector3D getTargetPosition(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) { // transform from specified reference frame to body frame final Vector3D position = pvProv.getPosition(date, frame); final PVCoordinates pVWithoutDerivatives = new PVCoordinates(position); final StaticTransform refToBody = frame.getStaticTransformTo(shape.getBodyFrame(), date); return nadirRef(new TimeStampedPVCoordinates(date, pVWithoutDerivatives), refToBody).getPosition(); } /** {@inheritDoc} */ @Override public > TimeStampedFieldPVCoordinates getTargetPV(final FieldPVCoordinatesProvider pvProv, final FieldAbsoluteDate date, final Frame frame) { final TimeStampedFieldPVCoordinates pvCoordinatesInRef = pvProv.getPVCoordinates(date, frame); final Field field = date.getField(); if (pvCoordinatesInRef.getAcceleration().equals(FieldVector3D.getZero(field))) { // let us assume that there is no proper acceleration available, so need to use interpolation for derivatives return getTargetPVViaInterpolation(pvProv, date, frame); } else { // use automatic differentiation // build time dependent transform final FieldUnivariateDerivative2Field ud2Field = FieldUnivariateDerivative2Field.getUnivariateDerivative2Field(field); final T shift = date.durationFrom(date.toAbsoluteDate()); final FieldUnivariateDerivative2 dt = new FieldUnivariateDerivative2<>(shift, field.getOne(), field.getZero()); final FieldAbsoluteDate> ud2Date = new FieldAbsoluteDate<>(ud2Field, date.toAbsoluteDate()).shiftedBy(dt); final FieldStaticTransform> refToBody = frame.getStaticTransformTo(shape.getBodyFrame(), ud2Date); final FieldVector3D> positionInRefFrame = pvCoordinatesInRef.toUnivariateDerivative2Vector(); final FieldVector3D> positionInBodyFrame = refToBody.transformPosition(positionInRefFrame); // satellite position in geodetic coordinates final FieldGeodeticPoint> gpSat = shape.transform(positionInBodyFrame, getBodyFrame(), ud2Date); // nadir position in geodetic coordinates final FieldGeodeticPoint> gpNadir = new FieldGeodeticPoint<>(gpSat.getLatitude(), gpSat.getLongitude(), ud2Field.getZero()); // nadir point position in body frame final FieldVector3D> positionNadirInBodyFrame = shape.transform(gpNadir); // nadir point position in reference frame final FieldStaticTransform> bodyToRef = refToBody.getInverse(); final FieldVector3D> positionNadirInRefFrame = bodyToRef.transformPosition(positionNadirInBodyFrame); // put derivatives into proper object final FieldVector3D position = new FieldVector3D<>(positionNadirInRefFrame.getX().getValue(), positionNadirInRefFrame.getY().getValue(), positionNadirInRefFrame.getZ().getValue()); final FieldVector3D velocity = new FieldVector3D<>(positionNadirInRefFrame.getX().getFirstDerivative(), positionNadirInRefFrame.getY().getFirstDerivative(), positionNadirInRefFrame.getZ().getFirstDerivative()); final FieldVector3D acceleration = new FieldVector3D<>(positionNadirInRefFrame.getX().getSecondDerivative(), positionNadirInRefFrame.getY().getSecondDerivative(), positionNadirInRefFrame.getZ().getSecondDerivative()); return new TimeStampedFieldPVCoordinates<>(date, position, velocity, acceleration); } } /** * Compute target position-velocity-acceleration vector via interpolation (Field version). * @param pvProv PV provider * @param date date * @param frame frame * @param field type * @return target position-velocity-acceleration */ public > TimeStampedFieldPVCoordinates getTargetPVViaInterpolation(final FieldPVCoordinatesProvider pvProv, final FieldAbsoluteDate date, final Frame frame) { // zero final T zero = date.getField().getZero(); // transform from specified reference frame to body frame final FieldTransform refToBody = frame.getTransformTo(shape.getBodyFrame(), date); // sample intersection points in current date neighborhood final double h = 0.01; final List> sample = new ArrayList<>(); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-2 * h), frame), refToBody.staticShiftedBy(zero.newInstance(-2 * h)))); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(-h), frame), refToBody.staticShiftedBy(zero.newInstance(-h)))); sample.add(nadirRef(pvProv.getPVCoordinates(date, frame), refToBody)); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+h), frame), refToBody.staticShiftedBy(zero.newInstance(+h)))); sample.add(nadirRef(pvProv.getPVCoordinates(date.shiftedBy(+2 * h), frame), refToBody.staticShiftedBy(zero.newInstance(+2 * h)))); // create interpolator final FieldTimeInterpolator, T> interpolator = new TimeStampedFieldPVCoordinatesHermiteInterpolator<>(sample.size(), CartesianDerivativesFilter.USE_P); // use interpolation to compute properly the time-derivatives return interpolator.interpolate(date, sample); } /** {@inheritDoc} */ @Override protected > FieldVector3D getTargetPosition(final FieldPVCoordinatesProvider pvProv, final FieldAbsoluteDate date, final Frame frame) { // transform from specified reference frame to body frame final FieldVector3D position = pvProv.getPosition(date, frame); final FieldPVCoordinates pVWithoutDerivatives = new FieldPVCoordinates<>(position, FieldVector3D.getZero(date.getField())); final FieldStaticTransform refToBody = frame.getStaticTransformTo(shape.getBodyFrame(), date); return nadirRef(new TimeStampedFieldPVCoordinates(date, pVWithoutDerivatives), refToBody).getPosition(); } /** Compute ground point in nadir direction, in reference frame. * @param scRef spacecraft coordinates in reference frame * @param refToBody transform from reference frame to body frame * @return intersection point in body frame (only the position is set!) */ private TimeStampedPVCoordinates nadirRef(final TimeStampedPVCoordinates scRef, final StaticTransform refToBody) { final Vector3D satInBodyFrame = refToBody.transformPosition(scRef.getPosition()); // satellite position in geodetic coordinates final GeodeticPoint gpSat = shape.transform(satInBodyFrame, getBodyFrame(), scRef.getDate()); // nadir position in geodetic coordinates final GeodeticPoint gpNadir = new GeodeticPoint(gpSat.getLatitude(), gpSat.getLongitude(), 0.0); // nadir point position in body frame final Vector3D pNadirBody = shape.transform(gpNadir); // nadir point position in reference frame final Vector3D pNadirRef = refToBody.getInverse().transformPosition(pNadirBody); return new TimeStampedPVCoordinates(scRef.getDate(), pNadirRef, Vector3D.ZERO, Vector3D.ZERO); } /** Compute ground point in nadir direction, in reference frame. * @param scRef spacecraft coordinates in reference frame * @param refToBody transform from reference frame to body frame * @param type of the field elements * @return intersection point in body frame (only the position is set!) * @since 9.0 */ private > TimeStampedFieldPVCoordinates nadirRef(final TimeStampedFieldPVCoordinates scRef, final FieldStaticTransform refToBody) { final FieldVector3D satInBodyFrame = refToBody.transformPosition(scRef.getPosition()); // satellite position in geodetic coordinates final FieldGeodeticPoint gpSat = shape.transform(satInBodyFrame, getBodyFrame(), scRef.getDate()); // nadir position in geodetic coordinates final FieldGeodeticPoint gpNadir = new FieldGeodeticPoint<>(gpSat.getLatitude(), gpSat.getLongitude(), gpSat.getAltitude().getField().getZero()); // nadir point position in body frame final FieldVector3D pNadirBody = shape.transform(gpNadir); // nadir point position in reference frame final FieldVector3D pNadirRef = refToBody.getInverse().transformPosition(pNadirBody); final FieldVector3D zero = FieldVector3D.getZero(gpSat.getAltitude().getField()); return new TimeStampedFieldPVCoordinates<>(scRef.getDate(), pNadirRef, zero, zero); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy