/* 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 java.util.ArrayList; import java.util.List; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.orekit.Utils; import org.orekit.bodies.CelestialBodyFactory; import org.orekit.errors.OrekitException; import org.orekit.frames.FramesFactory; import org.orekit.orbits.EquinoctialOrbit; import org.orekit.orbits.Orbit; import org.orekit.propagation.Propagator; import org.orekit.propagation.SpacecraftState; import org.orekit.propagation.analytical.EcksteinHechlerPropagator; import org.orekit.propagation.events.handlers.EventHandler; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.PVCoordinates; public class EventShifterTest { private double mu; private AbsoluteDate iniDate; private Propagator propagator; private List<EventEntry> log; private double sunRadius = 696000000.; private double earthRadius = 6400000.; @Test public void testNegNeg() throws OrekitException { propagator.addEventDetector(createRawDetector("raw increasing", "raw decreasing", 1.0e-9)); EclipseDetector raw = createRawDetector("shifted increasing", "shifted decreasing", 1.0e-3); final EventHandler<? super EclipseDetector> h = raw.getHandler(); raw = raw.withHandler(new EventHandler<EclipseDetector>() { @Override public Action eventOccurred(SpacecraftState s, EclipseDetector detector, boolean increasing) throws OrekitException { h.eventOccurred(s, detector, increasing); return Action.RESET_STATE; } @Override public SpacecraftState resetState(EclipseDetector detector, SpacecraftState oldState) throws OrekitException { return h.resetState(detector, oldState); } }); EventShifter<EclipseDetector> shifter = new EventShifter<EclipseDetector>(raw, true, -15, -20). withMaxIter(200); Assert.assertEquals(-15, shifter.getIncreasingTimeShift(), 1.0e-15); Assert.assertEquals(-20, shifter.getDecreasingTimeShift(), 1.0e-15); Assert.assertEquals(200, shifter.getMaxIterationCount()); Assert.assertEquals(100, raw.getMaxIterationCount()); propagator.addEventDetector(shifter); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("unshifted increasing", "unshifted decreasing", 1.0e-3), false, -5, -10)); propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(6, log.size()); log.get(0).checkExpected(log.get(2).getDT() - 20, "shifted decreasing"); log.get(1).checkExpected(log.get(2).getDT(), "unshifted decreasing"); log.get(3).checkExpected(log.get(5).getDT() - 15, "shifted increasing"); log.get(4).checkExpected(log.get(5).getDT(), "unshifted increasing"); } @Test public void testNegPos() throws OrekitException { propagator.addEventDetector(createRawDetector("raw increasing", "raw decreasing", 1.0e-9)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("shifted increasing", "shifted decreasing", 1.0e-3), true, -15, 20)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("unshifted increasing", "unshifted decreasing", 1.0e-3), false, -5, 10)); propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(6, log.size()); log.get(1).checkExpected(log.get(0).getDT(), "unshifted decreasing"); log.get(2).checkExpected(log.get(0).getDT() + 20, "shifted decreasing"); log.get(3).checkExpected(log.get(5).getDT() - 15, "shifted increasing"); log.get(4).checkExpected(log.get(5).getDT(), "unshifted increasing"); } @Test public void testPosNeg() throws OrekitException { propagator.addEventDetector(createRawDetector("raw increasing", "raw decreasing", 1.0e-9)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("shifted increasing", "shifted decreasing", 1.0e-3), true, 15, -20)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("unshifted increasing", "unshifted decreasing", 1.0e-3), false, 5, -10)); propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(6, log.size()); log.get(0).checkExpected(log.get(2).getDT() - 20, "shifted decreasing"); log.get(1).checkExpected(log.get(2).getDT(), "unshifted decreasing"); log.get(4).checkExpected(log.get(3).getDT(), "unshifted increasing"); log.get(5).checkExpected(log.get(3).getDT() + 15, "shifted increasing"); } @Test public void testPosPos() throws OrekitException { propagator.addEventDetector(createRawDetector("raw increasing", "raw decreasing", 1.0e-9)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("shifted increasing", "shifted decreasing", 1.0e-3), true, 15, 20)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("unshifted increasing", "unshifted decreasing", 1.0e-3), false, 5, 10)); propagator.propagate(iniDate.shiftedBy(6000)); Assert.assertEquals(6, log.size()); log.get(1).checkExpected(log.get(0).getDT(), "unshifted decreasing"); log.get(2).checkExpected(log.get(0).getDT() + 20, "shifted decreasing"); log.get(4).checkExpected(log.get(3).getDT(), "unshifted increasing"); log.get(5).checkExpected(log.get(3).getDT() + 15, "shifted increasing"); } @Test public void testIncreasingError() throws OrekitException { propagator.addEventDetector(createRawDetector("raw increasing", "raw decreasing", 2.0e-9)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("-10s increasing", "-10s decreasing", 2.0e-3), true, -10, -10)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("-100s increasing", "-100s decreasing", 3.0e-2), true, -100, -100)); propagator.addEventDetector(new EventShifter<EclipseDetector>(createRawDetector("-1000s increasing", "-1000s decreasing", 5.0), true, -1000, -1000)); propagator.propagate(iniDate.shiftedBy(20100)); // the raw eclipses (not all within the propagation range) are at times: // [ 2300.238, 4376.986] // [ 8210.859, 10287.573] // [14121.478, 16198.159] // [20032.098, 22108.745] // [25942.717, 28019.331] // [31853.335, 33929.916] // [37763.954, 39840.500] Assert.assertEquals(28, log.size()); for (int i = 0; i < log.size() / 4; ++i) { EventEntry ref = log.get(4 * i + 3); String increasingOrDecreasing = ref.getName().split(" ")[1]; log.get(4 * i + 0).checkExpected(ref.getDT() - 1000, "-1000s " + increasingOrDecreasing); log.get(4 * i + 1).checkExpected(ref.getDT() - 100, "-100s " + increasingOrDecreasing); log.get(4 * i + 2).checkExpected(ref.getDT() - 10, "-10s " + increasingOrDecreasing); } for (EventEntry entry : log) { double error = entry.getTimeError(); if (entry.name.contains("10s")) { Assert.assertTrue(error > 0.00001); Assert.assertTrue(error < 0.0003); } else if (entry.name.contains("100s")) { Assert.assertTrue(error > 0.002); Assert.assertTrue(error < 0.03); } else if (entry.name.contains("1000s")) { Assert.assertTrue(error > 0.7); Assert.assertTrue(error < 3.3); } } } private EclipseDetector createRawDetector(final String nameIncreasing, final String nameDecreasing, final double tolerance) throws OrekitException { return new EclipseDetector(60., 1.e-10, CelestialBodyFactory.getSun(), sunRadius, CelestialBodyFactory.getEarth(), earthRadius). withHandler(new EventHandler<EclipseDetector>() { public Action eventOccurred(SpacecraftState s, EclipseDetector detector, boolean increasing) { log.add(new EventEntry(s.getDate().durationFrom(iniDate), tolerance, increasing ? nameIncreasing : nameDecreasing)); return Action.CONTINUE; } }); } @Before public void setUp() { try { Utils.setDataRoot("regular-data"); mu = 3.9860047e14; double ae = 6.378137e6; double c20 = -1.08263e-3; double c30 = 2.54e-6; double c40 = 1.62e-6; double c50 = 2.3e-7; double c60 = -5.5e-7; final Vector3D position = new Vector3D(-6142438.668, 3492467.560, -25767.25680); final Vector3D velocity = new Vector3D(505.8479685, 942.7809215, 7435.922231); iniDate = new AbsoluteDate(1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT()); final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position, velocity), FramesFactory.getGCRF(), iniDate, mu); propagator = new EcksteinHechlerPropagator(orbit, ae, mu, c20, c30, c40, c50, c60); log = new ArrayList<EventEntry>(); } catch (OrekitException oe) { Assert.fail(oe.getLocalizedMessage()); } } @After public void tearDown() { iniDate = null; propagator = null; log = null; } private static class EventEntry { private final double dt; private double expectedDT; private final double tolerance; private final String name; public EventEntry(final double dt, final double tolerance, final String name) { this.dt = dt; this.expectedDT = Double.NaN; this.tolerance = tolerance; this.name = name; } public void checkExpected(final double expectedDT, final String name) { this.expectedDT = expectedDT; Assert.assertEquals(expectedDT, dt, tolerance); Assert.assertEquals(name, this.name); } public double getDT() { return dt; } public String getName() { return name; } public double getTimeError() { return FastMath.abs(dt - expectedDT); } } }