/* 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.List;
import org.hipparchus.Field;
import org.hipparchus.RealFieldElement;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.ode.nonstiff.AdaptiveStepsizeFieldIntegrator;
import org.hipparchus.ode.nonstiff.DormandPrince853FieldIntegrator;
import org.hipparchus.util.Decimal64Field;
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.FieldEquinoctialOrbit;
import org.orekit.orbits.FieldOrbit;
import org.orekit.orbits.OrbitType;
import org.orekit.propagation.FieldSpacecraftState;
import org.orekit.propagation.events.handlers.FieldEventHandler;
import org.orekit.propagation.numerical.FieldNumericalPropagator;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.FieldPVCoordinates;
public class FieldEventsLoggerTest {
private double mu;
// private FieldAbsoluteDate<T> iniDate;
// private FieldSpacecraftState<T> initialState;
private int count;
// private FieldEventDetector<T> umbraDetector;
// private FieldEventDetector<T> penumbraDetector;
@Before
public void setUp() {
Utils.setDataRoot("regular-data");
mu = 3.9860047e14;
}
@Test
public void testLogUmbra() throws OrekitException{
doTestLogUmbra(Decimal64Field.getInstance());
}
@Test
public void testLogPenumbra() throws OrekitException{
doTestLogPenumbra(Decimal64Field.getInstance());
}
@Test
public void testLogAll() throws OrekitException{
doTestLogAll(Decimal64Field.getInstance());
}
@Test
public void testImmutableList() throws OrekitException{
doTestImmutableList(Decimal64Field.getInstance());
}
@Test
public void testClearLog() throws OrekitException{
doTestClearLog(Decimal64Field.getInstance());
}
private <T extends RealFieldElement<T>> void doTestLogUmbra(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.getEME2000(), 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);
count = 0;
FieldEventDetector<T> umbraDetector = buildDetector(field, true);
FieldEventDetector<T> penumbraDetector = buildDetector(field, false);
FieldEventsLogger<T> logger = new FieldEventsLogger<T>();
@SuppressWarnings("unchecked")
FieldEventDetector<T> monitored = ((FieldAbstractDetector<FieldEventDetector<T>, T>) logger.monitorDetector(umbraDetector)).
withMaxIter(200);
Assert.assertEquals(100, umbraDetector.getMaxIterationCount());
Assert.assertEquals(200, monitored.getMaxIterationCount());
propagator.addEventDetector(monitored);
propagator.addEventDetector(penumbraDetector);
count = 0;
propagator.propagate(iniDate.shiftedBy(16215)).getDate();
Assert.assertEquals(11, count);
checkCounts(logger, 3, 3, 0, 0, umbraDetector, penumbraDetector);
}
private <T extends RealFieldElement<T>> void doTestLogPenumbra(final 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.getEME2000(), 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);
count = 0;
FieldEventDetector<T> umbraDetector = buildDetector(field, true);
FieldEventDetector<T> penumbraDetector = buildDetector(field, false);
FieldEventsLogger<T> logger = new FieldEventsLogger<T>();
propagator.addEventDetector(umbraDetector);
propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
count = 0;
propagator.propagate(iniDate.shiftedBy(16215)).getDate();
Assert.assertEquals(11, count);
checkCounts(logger, 0, 0, 2, 3, umbraDetector, penumbraDetector);
}
private <T extends RealFieldElement<T>> void doTestLogAll(final 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.getEME2000(), 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);
count = 0;
FieldEventDetector<T> umbraDetector = buildDetector(field, true);
FieldEventDetector<T> penumbraDetector = buildDetector(field, false);
FieldEventsLogger<T> logger = new FieldEventsLogger<T>();
propagator.addEventDetector(logger.monitorDetector(umbraDetector));
propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
count = 0;
propagator.propagate(iniDate.shiftedBy(16215));
Assert.assertEquals(11, count);
checkCounts(logger, 3, 3, 2, 3, umbraDetector, penumbraDetector);
}
private <T extends RealFieldElement<T>> void doTestImmutableList(final 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.getEME2000(), 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);
count = 0;
FieldEventDetector<T> umbraDetector = buildDetector(field, true);
FieldEventDetector<T> penumbraDetector = buildDetector(field, false);
FieldEventsLogger<T> logger = new FieldEventsLogger<T>();
propagator.addEventDetector(logger.monitorDetector(umbraDetector));
propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
count = 0;
propagator.propagate(iniDate.shiftedBy(16215));
List<FieldEventsLogger.FieldLoggedEvent<T>> firstList = logger.getLoggedEvents();
Assert.assertEquals(11, firstList.size());
propagator.propagate(iniDate.shiftedBy(30000));
List<FieldEventsLogger.FieldLoggedEvent<T>> secondList = logger.getLoggedEvents();
Assert.assertEquals(11, firstList.size());
Assert.assertEquals(20, secondList.size());
for (int i = 0; i < firstList.size(); ++i) {
FieldEventsLogger.FieldLoggedEvent<T> e1 = firstList.get(i);
FieldEventsLogger.FieldLoggedEvent<T> e2 = secondList.get(i);
FieldPVCoordinates<T> pv1 = e1.getState().getPVCoordinates();
FieldPVCoordinates<T> pv2 = e2.getState().getPVCoordinates();
Assert.assertTrue(e1.getEventDetector() == e2.getEventDetector());
Assert.assertEquals(0, pv1.getPosition().subtract(pv2.getPosition()).getNorm().getReal(), 1.0e-10);
Assert.assertEquals(0, pv1.getVelocity().subtract(pv2.getVelocity()).getNorm().getReal(), 1.0e-10);
Assert.assertEquals(e1.isIncreasing(), e2.isIncreasing());
}
}
private <T extends RealFieldElement<T>> void doTestClearLog(final 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.getEME2000(), 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);
count = 0;
FieldEventDetector<T> umbraDetector = buildDetector(field, true);
FieldEventDetector<T> penumbraDetector = buildDetector(field, false);
FieldEventsLogger<T> logger = new FieldEventsLogger<T>();
propagator.addEventDetector(logger.monitorDetector(umbraDetector));
propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
count = 0;
propagator.propagate(iniDate.shiftedBy(16215));
List<FieldEventsLogger.FieldLoggedEvent<T>> firstList = logger.getLoggedEvents();
Assert.assertEquals(11, firstList.size());
logger.clearLoggedEvents();
propagator.propagate(iniDate.shiftedBy(30000));
List<FieldEventsLogger.FieldLoggedEvent<T>> secondList = logger.getLoggedEvents();
Assert.assertEquals(11, firstList.size());
Assert.assertEquals( 9, secondList.size());
}
private <T extends RealFieldElement<T>> void checkCounts(FieldEventsLogger<T> logger,
int expectedUmbraIncreasingCount, int expectedUmbraDecreasingCount,
int expectedPenumbraIncreasingCount, int expectedPenumbraDecreasingCount,
FieldEventDetector<T> umbraDetector, FieldEventDetector<T> penumbraDetector) {
int umbraIncreasingCount = 0;
int umbraDecreasingCount = 0;
int penumbraIncreasingCount = 0;
int penumbraDecreasingCount = 0;
for (FieldEventsLogger.FieldLoggedEvent<T> event : logger.getLoggedEvents()) {
if (event.getEventDetector() == umbraDetector) {
if (event.isIncreasing()) {
++umbraIncreasingCount;
} else {
++umbraDecreasingCount;
}
}
if (event.getEventDetector() == penumbraDetector) {
if (event.isIncreasing()) {
++penumbraIncreasingCount;
} else {
++penumbraDecreasingCount;
}
}
}
Assert.assertEquals(expectedUmbraIncreasingCount, umbraIncreasingCount);
Assert.assertEquals(expectedUmbraDecreasingCount, umbraDecreasingCount);
Assert.assertEquals(expectedPenumbraIncreasingCount, penumbraIncreasingCount);
Assert.assertEquals(expectedPenumbraDecreasingCount, penumbraDecreasingCount);
}
private <T extends RealFieldElement<T>> FieldEventDetector<T> buildDetector(Field<T> field, final boolean totalEclipse) throws OrekitException {
FieldEclipseDetector<T> detector =
new FieldEclipseDetector<T>(field.getZero().add(60.), field.getZero().add(1.e-3), CelestialBodyFactory.getSun(), 696000000,
CelestialBodyFactory.getEarth(), 6400000);
if (totalEclipse) {
detector = detector.withUmbra();
} else {
detector = detector.withPenumbra();
}
detector = detector.withHandler(new FieldEventHandler<FieldEclipseDetector<T>, T>() {
public Action eventOccurred(FieldSpacecraftState<T> s, FieldEclipseDetector<T> detector, boolean increasing) {
++count;
return Action.CONTINUE;
}
} );
return detector;
}
@After
public void tearDown() {
count = 0;
}
}