/* Copyright 2002-2017 CS Systèmes d'Information * Licensed to CS Systèmes d'Information (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.Field; import org.hipparchus.RealFieldElement; import org.hipparchus.geometry.euclidean.threed.FieldRotation; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.Decimal64Field; import org.hipparchus.util.FastMath; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.orekit.Utils; import org.orekit.errors.OrekitException; import org.orekit.frames.Frame; import org.orekit.frames.FramesFactory; import org.orekit.orbits.FieldKeplerianOrbit; import org.orekit.orbits.FieldOrbit; import org.orekit.orbits.PositionAngle; import org.orekit.propagation.FieldPropagator; import org.orekit.propagation.FieldSpacecraftState; import org.orekit.propagation.analytical.FieldKeplerianPropagator; import org.orekit.time.DateComponents; import org.orekit.time.FieldAbsoluteDate; import org.orekit.time.TimeComponents; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.FieldAngularCoordinates; import org.orekit.utils.FieldPVCoordinates; import org.orekit.utils.PVCoordinates; public class FieldFixedRateTest { @Test public void testZeroRate() throws OrekitException { doTestZeroRate(Decimal64Field.getInstance()); } private <T extends RealFieldElement<T>> void doTestZeroRate(final Field<T> field) throws OrekitException { final T zero = field.getZero(); FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 3, 2), new TimeComponents(13, 17, 7.865), TimeScalesFactory.getUTC()); final Frame frame = FramesFactory.getEME2000(); final FieldVector3D<T> zero3D = new FieldVector3D<>(zero, zero, zero); FieldFixedRate<T> law = new FieldFixedRate<>(new FieldAttitude<>(date, frame, new FieldRotation<>(zero.add(0.48), zero.add(0.64), zero.add(0.36), zero.add(0.48), false), zero3D, zero3D)); FieldPVCoordinates<T> pv = new FieldPVCoordinates<>(field.getOne(), new PVCoordinates(new Vector3D(28812595.32012577, 5948437.4640250085, 0), new Vector3D(0, 0, 3680.853673522056))); FieldOrbit<T> orbit = new FieldKeplerianOrbit<>(pv, frame, date, 3.986004415e14); FieldRotation<T> attitude0 = law.getAttitude(orbit, date, frame).getRotation(); Assert.assertEquals(0, FieldRotation.distance(attitude0, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); FieldRotation<T> attitude1 = law.getAttitude(orbit.shiftedBy(zero.add(10.0)), date.shiftedBy(10.0), frame).getRotation(); Assert.assertEquals(0, FieldRotation.distance(attitude1, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); FieldRotation<T> attitude2 = law.getAttitude(orbit.shiftedBy(zero.add(20.0)), date.shiftedBy(20.0), frame).getRotation(); Assert.assertEquals(0, FieldRotation.distance(attitude2, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); } @Test public void testNonZeroRate() throws OrekitException { doTestNonZeroRate(Decimal64Field.getInstance()); } private <T extends RealFieldElement<T>> void doTestNonZeroRate(final Field<T> field) throws OrekitException { final T zero = field.getZero(); FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 3, 2), new TimeComponents(13, 17, 7.865), TimeScalesFactory.getUTC()); final T rate = zero.add(2 * FastMath.PI / (12 * 60)); final Frame frame = FramesFactory.getEME2000(); final FieldVector3D<T> zero3D = new FieldVector3D<>(zero, zero, zero); FieldFixedRate<T> law = new FieldFixedRate<>(new FieldAttitude<>(date, frame, new FieldRotation<>(zero.add(0.48), zero.add(0.64), zero.add(0.36), zero.add(0.48), false), new FieldVector3D<>(rate, Vector3D.PLUS_K), zero3D)); FieldPVCoordinates<T> pv = new FieldPVCoordinates<>(field.getOne(), new PVCoordinates(new Vector3D(28812595.32012577, 5948437.4640250085, 0), new Vector3D(0, 0, 3680.853673522056))); FieldOrbit<T> orbit = new FieldKeplerianOrbit<>(pv, FramesFactory.getEME2000(), date, 3.986004415e14); FieldRotation<T> attitude0 = law.getAttitude(orbit, date, frame).getRotation(); Assert.assertEquals(0, FieldRotation.distance(attitude0, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); FieldRotation<T> attitude1 = law.getAttitude(orbit.shiftedBy(zero.add(10.0)), date.shiftedBy(10.0), frame).getRotation(); Assert.assertEquals(10 * rate.getReal(), FieldRotation.distance(attitude1, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); FieldRotation<T> attitude2 = law.getAttitude(orbit.shiftedBy(zero.add(-20.0)), date.shiftedBy(-20.0), frame).getRotation(); Assert.assertEquals(20 * rate.getReal(), FieldRotation.distance(attitude2, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); Assert.assertEquals(30 * rate.getReal(), FieldRotation.distance(attitude2, attitude1).getReal(), 1.0e-10); FieldRotation<T> attitude3 = law.getAttitude(orbit.shiftedBy(zero.add(0.0)), date, frame).getRotation(); Assert.assertEquals(0, FieldRotation.distance(attitude3, law.getReferenceAttitude().getRotation()).getReal(), 1.0e-10); } @Test public void testSpin() throws OrekitException { doTestSpin(Decimal64Field.getInstance()); } private <T extends RealFieldElement<T>> void doTestSpin(final Field<T> field) throws OrekitException { final T zero = field.getZero(); FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(1970, 01, 01), new TimeComponents(3, 25, 45.6789), TimeScalesFactory.getUTC()); final T rate = zero.add(2 * FastMath.PI / (12 * 60)); final FieldVector3D<T> zero3D = new FieldVector3D<>(zero, zero, zero); FieldAttitudeProvider<T> law = new FieldFixedRate<>(new FieldAttitude<>(date, FramesFactory.getEME2000(), new FieldRotation<>(zero.add(0.48), zero.add(0.64), zero.add(0.36), zero.add(0.48), false), new FieldVector3D<>(rate, Vector3D.PLUS_K), zero3D)); FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(zero.add(7178000.0), zero.add(1.e-4), zero.add(FastMath.toRadians(50.)), zero.add(FastMath.toRadians(10.)), zero.add(FastMath.toRadians(20.)), zero.add(FastMath.toRadians(30.)), PositionAngle.MEAN, FramesFactory.getEME2000(), date, 3.986004415e14); FieldPropagator<T> propagator = new FieldKeplerianPropagator<>(orbit, law); T h = zero.add(0.01); FieldSpacecraftState<T> sMinus = propagator.propagate(date.shiftedBy(h.negate())); FieldSpacecraftState<T> s0 = propagator.propagate(date); FieldSpacecraftState<T> sPlus = propagator.propagate(date.shiftedBy(h)); // check spin is consistent with attitude evolution double errorAngleMinus = FieldRotation.distance(sMinus.shiftedBy(h).getAttitude().getRotation(), s0.getAttitude().getRotation()).getReal(); double evolutionAngleMinus = FieldRotation.distance(sMinus.getAttitude().getRotation(), s0.getAttitude().getRotation()).getReal(); Assert.assertEquals(0.0, errorAngleMinus, 1.0e-6 * evolutionAngleMinus); double errorAnglePlus = FieldRotation.distance(s0.getAttitude().getRotation(), sPlus.shiftedBy(h.negate()).getAttitude().getRotation()).getReal(); double evolutionAnglePlus = FieldRotation.distance(s0.getAttitude().getRotation(), sPlus.getAttitude().getRotation()).getReal(); Assert.assertEquals(0.0, errorAnglePlus, 1.0e-6 * evolutionAnglePlus); FieldVector3D<T> spin0 = s0.getAttitude().getSpin(); FieldVector3D<T> reference = FieldAngularCoordinates.estimateRate(sMinus.getAttitude().getRotation(), sPlus.getAttitude().getRotation(), h.multiply(2)); Assert.assertEquals(0.0, spin0.subtract(reference).getNorm().getReal(), 1.0e-14); } @Before public void setUp() { Utils.setDataRoot("regular-data"); } }