/* 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.propagation.events; import org.hipparchus.Field; import org.hipparchus.RealFieldElement; import org.hipparchus.exception.MathRuntimeException; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.ode.nonstiff.AdaptiveStepsizeFieldIntegrator; import org.hipparchus.ode.nonstiff.DormandPrince853FieldIntegrator; 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.bodies.CelestialBody; import org.orekit.bodies.CelestialBodyFactory; import org.orekit.errors.OrekitException; import org.orekit.frames.FramesFactory; import org.orekit.orbits.FieldCartesianOrbit; import org.orekit.orbits.FieldEquinoctialOrbit; import org.orekit.orbits.FieldOrbit; import org.orekit.orbits.OrbitType; import org.orekit.propagation.FieldSpacecraftState; import org.orekit.propagation.analytical.FieldKeplerianPropagator; import org.orekit.propagation.events.handlers.FieldStopOnDecreasing; import org.orekit.propagation.numerical.FieldNumericalPropagator; import org.orekit.time.AbsoluteDate; import org.orekit.time.FieldAbsoluteDate; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.FieldPVCoordinates; import org.orekit.utils.TimeStampedFieldPVCoordinates; public class FieldEclipseDetectorTest { private double mu; private CelestialBody sun; private CelestialBody earth; private double sunRadius; private double earthRadius; @Before public void setUp() { try { Utils.setDataRoot("regular-data"); sun = CelestialBodyFactory.getSun(); earth = CelestialBodyFactory.getEarth(); sunRadius = 696000000.; earthRadius = 6400000.; mu = 3.9860047e14; } catch (OrekitException oe) { Assert.fail(oe.getLocalizedMessage()); } } @Test public void testEclipse() throws OrekitException{ doTestEclipse(Decimal64Field.getInstance()); } @Test public void testPenumbra() throws OrekitException{ doTestPenumbra(Decimal64Field.getInstance()); } @Test public void testWithMethods() throws OrekitException{ doTestWithMethods(Decimal64Field.getInstance()); } @Test public void testInsideOcculting() throws OrekitException{ doTestInsideOcculting(Decimal64Field.getInstance()); } @Test public void testInsideOcculted() throws OrekitException{ doTestInsideOcculted(Decimal64Field.getInstance()); } @Test public void testTooSmallMaxIterationCount() throws OrekitException{ testTooSmallMaxIterationCount(Decimal64Field.getInstance()); } private <T extends RealFieldElement<T>> void doTestEclipse(Field<T> field) throws OrekitException { T zero = field.getZero(); final FieldVector3D<T> position = new FieldVector3D<T>(zero.add(-6142438.668), zero.add(3492467.560), zero.add(-25767.25680)); final FieldVector3D<T> velocity = new FieldVector3D<T>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231)); FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<T>(field,1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final FieldOrbit<T> orbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity), FramesFactory.getGCRF(), iniDate, mu); FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(orbit); FieldKeplerianPropagator<T> propagator = new FieldKeplerianPropagator<T>(orbit); propagator.resetInitialState(initialState); FieldEclipseDetector<T> e = new FieldEclipseDetector<T>(field.getZero().add(60.),field.getZero().add(1e-3), sun, sunRadius, earth, earthRadius). withHandler(new FieldStopOnDecreasing<FieldEclipseDetector<T>, T>()). withUmbra(); Assert.assertEquals(60.0, e.getMaxCheckInterval().getReal(), 1.0e-15); Assert.assertEquals(1.0e-3, e.getThreshold().getReal(), 1.0e-15); Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, e.getMaxIterationCount()); Assert.assertSame(sun, e.getOcculted()); Assert.assertEquals(sunRadius, e.getOccultedRadius(), 1.0); Assert.assertSame(earth, e.getOcculting()); Assert.assertEquals(earthRadius, e.getOccultingRadius(), 1.0); Assert.assertTrue(e.getTotalEclipse()); propagator.addEventDetector(e); final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(2303.1835, finalState.getDate().durationFrom(iniDate).getReal(), 1.0e-3); } private <T extends RealFieldElement<T>> void doTestPenumbra(Field<T> field) throws OrekitException { T zero = field.getZero(); final FieldVector3D<T> position = new FieldVector3D<T>(zero.add(-6142438.668), zero.add(3492467.560), zero.add(-25767.25680)); final FieldVector3D<T> velocity = new FieldVector3D<T>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231)); FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<T>(field,1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final FieldOrbit<T> orbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity), FramesFactory.getGCRF(), iniDate, mu); FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(orbit); double[] absTolerance = { 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001 }; double[] relTolerance = { 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7 }; AdaptiveStepsizeFieldIntegrator<T> integrator = new DormandPrince853FieldIntegrator<T>(field, 0.001, 1000, absTolerance, relTolerance); integrator.setInitialStepSize(field.getZero().add(60.)); FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator); propagator.setOrbitType(OrbitType.EQUINOCTIAL); propagator.setInitialState(initialState); sun = CelestialBodyFactory.getSun(); earth = CelestialBodyFactory.getEarth(); sunRadius = 696000000.; earthRadius = 6400000.; FieldEclipseDetector<T> e = new FieldEclipseDetector<T>(zero.add(60.), zero.add(1.e-3), sun, sunRadius, earth, earthRadius). withPenumbra(); Assert.assertFalse(e.getTotalEclipse()); propagator.addEventDetector(e); final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(4388.155852, finalState.getDate().durationFrom(iniDate).getReal(), 2.0e-6); } private <T extends RealFieldElement<T>> void doTestWithMethods(Field<T> field) throws OrekitException { T zero = field.getZero(); final FieldVector3D<T> position = new FieldVector3D<T>(zero.add(-6142438.668), zero.add(3492467.560), zero.add(-25767.25680)); final FieldVector3D<T> velocity = new FieldVector3D<T>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231)); FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<T>(field,1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final FieldOrbit<T> orbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity), FramesFactory.getGCRF(), iniDate, mu); FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(orbit); double[] absTolerance = { 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001 }; double[] relTolerance = { 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7 }; AdaptiveStepsizeFieldIntegrator<T> integrator = new DormandPrince853FieldIntegrator<T>(field, 0.001, 1000, absTolerance, relTolerance); integrator.setInitialStepSize(field.getZero().add(60)); FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator); propagator.setOrbitType(OrbitType.EQUINOCTIAL); propagator.setInitialState(initialState); sun = CelestialBodyFactory.getSun(); earth = CelestialBodyFactory.getEarth(); sunRadius = 696000000.; earthRadius = 6400000.; FieldEclipseDetector<T> e = new FieldEclipseDetector<T>(field.getZero().add(60.),field.getZero().add(1e-3), sun, sunRadius, earth, earthRadius). withHandler(new FieldStopOnDecreasing<FieldEclipseDetector<T>, T>()). withMaxCheck(field.getZero().add(120.0)). withThreshold(field.getZero().add(1.0e-4)). withMaxIter(12); Assert.assertEquals(120.0, e.getMaxCheckInterval().getReal(), 1.0e-15); Assert.assertEquals(1.0e-4, e.getThreshold().getReal(), 1.0e-15); Assert.assertEquals(12, e.getMaxIterationCount()); propagator.addEventDetector(e); final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(2303.1835, finalState.getDate().durationFrom(iniDate).getReal(), 1.0e-3); } private <T extends RealFieldElement<T>> void doTestInsideOcculting(Field<T> field) throws OrekitException { T zero = field.getZero(); final FieldVector3D<T> position = new FieldVector3D<T>(zero.add(-6142438.668), zero.add(3492467.560), zero.add(-25767.25680)); final FieldVector3D<T> velocity = new FieldVector3D<T>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231)); FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<T>(field,1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final FieldOrbit<T> orbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity), FramesFactory.getGCRF(), iniDate, mu); FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(orbit); double[] absTolerance = { 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001 }; double[] relTolerance = { 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7 }; AdaptiveStepsizeFieldIntegrator<T> integrator = new DormandPrince853FieldIntegrator<T>(field, 0.001, 1000, absTolerance, relTolerance); integrator.setInitialStepSize(field.getZero().add(60)); FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator); propagator.setOrbitType(OrbitType.EQUINOCTIAL); propagator.setInitialState(initialState); sun = CelestialBodyFactory.getSun(); earth = CelestialBodyFactory.getEarth(); sunRadius = 696000000.; earthRadius = 6400000.; FieldEclipseDetector<T> e = new FieldEclipseDetector<T>(field.getZero().add(60.), field.getZero().add(1.e-3), sun, sunRadius, earth, earthRadius); FieldSpacecraftState<T> s = new FieldSpacecraftState<T>(new FieldCartesianOrbit<T>(new TimeStampedFieldPVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), new FieldPVCoordinates<T>( new FieldVector3D<T>(field.getZero().add(1e6), field.getZero().add(2e6), field.getZero().add(3e6)), new FieldVector3D<T>(field.getZero().add(1000), field.getZero().add(0), field.getZero().add(0)))), FramesFactory.getGCRF(), mu)); Assert.assertEquals(-FastMath.PI, e.g(s).getReal(), 1.0e-15); } private <T extends RealFieldElement<T>> void doTestInsideOcculted(Field<T> field) throws OrekitException { T zero = field.getZero(); final FieldVector3D<T> position = new FieldVector3D<T>(zero.add(-6142438.668), zero.add(3492467.560), zero.add(-25767.25680)); final FieldVector3D<T> velocity = new FieldVector3D<T>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231)); FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<T>(field,1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final FieldOrbit<T> orbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity), FramesFactory.getGCRF(), iniDate, mu); FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(orbit); double[] absTolerance = { 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001 }; double[] relTolerance = { 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7 }; AdaptiveStepsizeFieldIntegrator<T> integrator = new DormandPrince853FieldIntegrator<T>(field, 0.001, 1000, absTolerance, relTolerance); integrator.setInitialStepSize(field.getZero().add(60)); FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator); propagator.setOrbitType(OrbitType.EQUINOCTIAL); propagator.setInitialState(initialState); sun = CelestialBodyFactory.getSun(); earth = CelestialBodyFactory.getEarth(); sunRadius = 696000000.; earthRadius = 6400000.; FieldEclipseDetector<T> e = new FieldEclipseDetector<T>(field.getZero().add(60.), field.getZero().add(1.e-3), sun, sunRadius, earth, earthRadius); Vector3D p = sun.getPVCoordinates(AbsoluteDate.J2000_EPOCH, FramesFactory.getGCRF()).getPosition(); FieldSpacecraftState<T> s = new FieldSpacecraftState<T>(new FieldCartesianOrbit<T>(new TimeStampedFieldPVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), new FieldPVCoordinates<T>( new FieldVector3D<T>(field.getOne(), field.getZero(), field.getZero()).add(p), new FieldVector3D<T>(field.getZero(), field.getZero(), field.getOne()))), FramesFactory.getGCRF(), mu)); Assert.assertEquals(FastMath.PI, e.g(s).getReal(), 1.0e-15); } private <T extends RealFieldElement<T>> void testTooSmallMaxIterationCount(Field<T> field) throws OrekitException { T zero = field.getZero(); final FieldVector3D<T> position = new FieldVector3D<T>(zero.add(-6142438.668), zero.add(3492467.560), zero.add(-25767.25680)); final FieldVector3D<T> velocity = new FieldVector3D<T>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231)); FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<T>(field,1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final FieldOrbit<T> orbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity), FramesFactory.getGCRF(), iniDate, mu); FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(orbit); double[] absTolerance = { 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001 }; double[] relTolerance = { 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7 }; AdaptiveStepsizeFieldIntegrator<T> integrator = new DormandPrince853FieldIntegrator<T>(field, 0.001, 1000, absTolerance, relTolerance); integrator.setInitialStepSize(field.getZero().add(60)); FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator); propagator.setOrbitType(OrbitType.EQUINOCTIAL); propagator.setInitialState(initialState); sun = CelestialBodyFactory.getSun(); earth = CelestialBodyFactory.getEarth(); sunRadius = 696000000.; earthRadius = 6400000.; int n = 5; FieldEclipseDetector<T> e = new FieldEclipseDetector<T>(field.getZero().add(60.), field.getZero().add(1.e-3), sun, sunRadius, earth, earthRadius). withHandler(new FieldStopOnDecreasing<FieldEclipseDetector<T>, T>()). withMaxCheck(field.getZero().add(120.0)). withThreshold(field.getZero().add(1.0e-4)). withMaxIter(n); propagator.addEventDetector(e); try { propagator.propagate(iniDate.shiftedBy(6000)); Assert.fail("an exception should have been thrown"); } catch (OrekitException oe) { Assert.assertEquals(n, ((Integer) ((MathRuntimeException) oe.getCause()).getParts()[0]).intValue()); } } } //