/* 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.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.ode.nonstiff.AdaptiveStepsizeFieldIntegrator;
import org.hipparchus.ode.nonstiff.DormandPrince853FieldIntegrator;
import org.hipparchus.util.Decimal64Field;
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.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.FieldContinueOnEvent;
import org.orekit.propagation.events.handlers.FieldEventHandler;
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;
public class FieldDateDetectorTest {
private int evtno = 0;
private double maxCheck;
private double threshold;
private double dt;
private double mu;
private AbsoluteDate nodeDate;
@Test
public void testSimpleTimer() throws OrekitException{
doTestSimpleTimer(Decimal64Field.getInstance());
}
@Test
public void testEmbeddedTimer() throws OrekitException{
doTestEmbeddedTimer(Decimal64Field.getInstance());
}
@Test
public void testAutoEmbeddedTimer() throws OrekitException{
doTestAutoEmbeddedTimer(Decimal64Field.getInstance());
}
@Test(expected=IllegalArgumentException.class)
public void testExceptionTimer() throws OrekitException{
doTestExceptionTimer(Decimal64Field.getInstance());
}
@Test
public void testGenericHandler() throws OrekitException{
doTestGenericHandler(Decimal64Field.getInstance());
}
private <T extends RealFieldElement<T>> void doTestSimpleTimer(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());
FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity),
FramesFactory.getEME2000(), iniDate, mu);
FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(iniOrbit);
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(zero.add(60));
FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<T>(field, integrator);
propagator.setOrbitType(OrbitType.EQUINOCTIAL);
propagator.setInitialState(initialState);
FieldDateDetector<T> dateDetector = new FieldDateDetector<T> (zero.add(maxCheck), zero.add(threshold), iniDate.shiftedBy(2.0*dt));
Assert.assertEquals(2 * dt, dateDetector.getDate().durationFrom(iniDate).getReal(), 1.0e-10);
propagator.addEventDetector(dateDetector);
final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(100.*dt));
Assert.assertEquals(2.0*dt, finalState.getDate().durationFrom(iniDate).getReal(), threshold);
}
private <T extends RealFieldElement<T>> void doTestEmbeddedTimer(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());
FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity),
FramesFactory.getEME2000(), iniDate, mu);
FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(iniOrbit);
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(zero.add(60));
FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<T>(field, integrator);
propagator.setOrbitType(OrbitType.EQUINOCTIAL);
propagator.setInitialState(initialState);
FieldDateDetector<T> dateDetector = new FieldDateDetector<T> (zero.add(maxCheck), zero.add(threshold));
Assert.assertNull(dateDetector.getDate());
FieldEventDetector<T> nodeDetector = new FieldNodeDetector<T>(iniOrbit, iniOrbit.getFrame()).
withHandler(new FieldContinueOnEvent<FieldNodeDetector<T>, T>() {
public Action eventOccurred(FieldSpacecraftState<T> s, FieldNodeDetector<T> nd, boolean increasing)
throws OrekitException {
if (increasing) {
nodeDate = s.getDate().toAbsoluteDate();
dateDetector.addEventDate(s.getDate().shiftedBy(dt));
}
return Action.CONTINUE;
}
});
propagator.addEventDetector(nodeDetector);
propagator.addEventDetector(dateDetector);
final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(100.*dt));
Assert.assertEquals(dt, finalState.getDate().durationFrom(nodeDate).getReal(), threshold);
}
private <T extends RealFieldElement<T>> void doTestAutoEmbeddedTimer(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());
FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity),
FramesFactory.getEME2000(), iniDate, mu);
FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(iniOrbit);
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(zero.add(60));
FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<T>(field, integrator);
propagator.setOrbitType(OrbitType.EQUINOCTIAL);
propagator.setInitialState(initialState);
FieldDateDetector<T> dateDetector = new FieldDateDetector<T> (zero.add(maxCheck), zero.add(threshold), iniDate.shiftedBy(-dt)).
withHandler(new FieldContinueOnEvent<FieldDateDetector<T>, T >() {
public Action eventOccurred(FieldSpacecraftState<T> s, FieldDateDetector<T> dd, boolean increasing)
throws OrekitException {
FieldAbsoluteDate<T> nextDate = s.getDate().shiftedBy(-dt);
dd.addEventDate(nextDate);
++evtno;
return Action.CONTINUE;
}
});
propagator.addEventDetector(dateDetector);
propagator.propagate(iniDate.shiftedBy(-100.*dt));
Assert.assertEquals(100, evtno);
}
private <T extends RealFieldElement<T>> void doTestExceptionTimer(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());
FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity),
FramesFactory.getEME2000(), iniDate, mu);
FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(iniOrbit);
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(zero.add(60));
FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<T>(field, integrator);
propagator.setOrbitType(OrbitType.EQUINOCTIAL);
propagator.setInitialState(initialState);
FieldDateDetector<T> dateDetector = new FieldDateDetector<T> (zero.add(maxCheck), zero.add(threshold), iniDate.shiftedBy(dt)).
withHandler(new FieldContinueOnEvent<FieldDateDetector<T>, T >() {
public Action eventOccurred(FieldSpacecraftState<T> s, FieldDateDetector<T> dd, boolean increasing)
throws OrekitException {
double step = (evtno % 2 == 0) ? 2.*maxCheck : maxCheck/2.;
FieldAbsoluteDate<T> nextDate = s.getDate().shiftedBy(step);
dd.addEventDate(nextDate);
++evtno;
return Action.CONTINUE;
}
});
propagator.addEventDetector(dateDetector);
propagator.propagate(iniDate.shiftedBy(100.*dt));
}
/**
* Check that a generic event handler can be used with an event detector.
*
* @throws OrekitException on error.
*/
private <T extends RealFieldElement<T>> void doTestGenericHandler(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());
FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<T>(new FieldPVCoordinates<T>(position, velocity),
FramesFactory.getEME2000(), iniDate, mu);
FieldSpacecraftState<T> initialState = new FieldSpacecraftState<T>(iniOrbit);
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(zero.add(60));
FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<T>(field, integrator);
propagator.setOrbitType(OrbitType.EQUINOCTIAL);
propagator.setInitialState(initialState);
//setup
final FieldDateDetector<T> dateDetector = new FieldDateDetector<T> (zero.add(maxCheck), zero.add(threshold), iniDate.shiftedBy(dt));
// generic event handler that works with all detectors.
FieldEventHandler<FieldEventDetector<T>, T> handler = new FieldEventHandler<FieldEventDetector<T>, T>() {
@Override
public Action eventOccurred(FieldSpacecraftState<T> s,
FieldEventDetector<T> detector,
boolean increasing)
throws OrekitException {
return Action.STOP;
}
@Override
public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector,
FieldSpacecraftState<T> oldState)
throws OrekitException {
throw new RuntimeException("Should not be called");
}
};
//action
final FieldDateDetector<T> dateDetector2;
dateDetector2 = dateDetector.withHandler(handler);
propagator.addEventDetector(dateDetector2);
FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(100 * dt));
//verify
Assert.assertEquals(dt, finalState.getDate().durationFrom(iniDate).getReal(), threshold);
}
@Before
public void setUp() {
Utils.setDataRoot("regular-data");
mu = 3.9860047e14;
dt = 60.;
maxCheck = 10.;
threshold = 10.e-7;
evtno = 0;
}
}