Commit 235f59e0 authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Fixed parameters observers.

parent 48cc7739
......@@ -16,6 +16,9 @@
*/
package org.orekit.propagation.events;
import java.util.List;
import java.util.stream.Collectors;
import org.hipparchus.util.FastMath;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
......@@ -29,11 +32,13 @@ import org.orekit.utils.ParameterObserver;
/** Detector for date intervals that may be offset thanks to parameter drivers.
* <p>
* {@link #getStartDriver() start}/{@link #getStopDriver() stop} drivers and
* {@link #getMedianDriver() median}/{@link #getDurationDriver() duration} drivers
* work in pair. Both drivers in one par can be selected and their changes will
* Two dual views can be used for date intervals: either start date/stop date or
* median date/duration. {@link #getStartDriver() start}/{@link #getStopDriver() stop}
* drivers and {@link #getMedianDriver() median}/{@link #getDurationDriver() duration}
* drivers work in pair. Both drivers in one pair can be selected and their changes will
* be propagated to the other pair, but attempting to select drivers in both
* pairs at the same time will trigger an exception.
* pairs at the same time will trigger an exception. Changing the value of a driver
* that is not selected should be avoided as it leads to inconsistencies between the pairs.
* </p>
* @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
* @author Luc Maisonobe
......@@ -65,6 +70,18 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
/** Duration driver. */
private ParameterDriver duration;
/** Build a new instance.
* @param prefix prefix to use for parameter drivers names
* @param refMedian reference interval median date
* @param refDuration reference duration
*/
public ParameterDrivenDateIntervalDetector(final String prefix,
final AbsoluteDate refMedian, final double refDuration) {
this(prefix,
refMedian.shiftedBy(-0.5 * refDuration),
refMedian.shiftedBy(+0.5 * refDuration));
}
/** Build a new instance.
* @param prefix prefix to use for parameter drivers names
* @param refStart reference interval start date
......@@ -106,10 +123,28 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
this.duration = duration;
// set up delegation between drivers
start.addObserver(new StartObserver());
stop.addObserver(new StopObserver());
median.addObserver(new MedianObserver());
duration.addObserver(new DurationObserver());
replaceBindingObserver(start, new StartObserver());
replaceBindingObserver(stop, new StopObserver());
replaceBindingObserver(median, new MedianObserver());
replaceBindingObserver(duration, new DurationObserver());
}
/** Replace binding observers.
* @param driver driver for whose binding observers should be replaced
* @param bindingObserver new binding observer
*/
private void replaceBindingObserver(final ParameterDriver driver, final BindingObserver bindingObserver) {
// remove the previous binding observers
final List<ParameterObserver> original = driver.
getObservers().
stream().
filter(observer -> observer instanceof BindingObserver).
collect(Collectors.toList());
original.forEach(observer -> driver.removeObserver(observer));
driver.addObserver(bindingObserver);
}
......@@ -187,7 +222,7 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
}
/** Base observer. */
private abstract class Observer implements ParameterObserver {
private abstract class BindingObserver implements ParameterObserver {
/** {@inheritDoc} */
@Override
......@@ -216,7 +251,7 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
}
/** Observer for start date. */
private class StartObserver extends Observer {
private class StartObserver extends BindingObserver {
/** {@inheritDoc} */
@Override
protected void setDelta(final double delta) {
......@@ -226,7 +261,7 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
}
/** Observer for stop date. */
private class StopObserver extends Observer {
private class StopObserver extends BindingObserver {
/** {@inheritDoc} */
@Override
protected void setDelta(final double delta) {
......@@ -236,7 +271,7 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
}
/** Observer for median date. */
private class MedianObserver extends Observer {
private class MedianObserver extends BindingObserver {
/** {@inheritDoc} */
@Override
protected void setDelta(final double delta) {
......@@ -246,7 +281,7 @@ public class ParameterDrivenDateIntervalDetector extends AbstractDetector<Parame
}
/** Observer for duration. */
private class DurationObserver extends Observer {
private class DurationObserver extends BindingObserver {
/** {@inheritDoc} */
@Override
protected void setDelta(final double delta) {
......
......@@ -21,6 +21,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.frames.FramesFactory;
import org.orekit.orbits.CartesianOrbit;
import org.orekit.orbits.Orbit;
......@@ -32,6 +34,7 @@ import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.ParameterDriver;
public class ParameterDrivenDateIntervalDetectorTest {
......@@ -96,10 +99,12 @@ public class ParameterDrivenDateIntervalDetectorTest {
@Test
public void testLargeShift() {
final AbsoluteDate t0 = propagator.getInitialState().getDate();
final AbsoluteDate start = t0.shiftedBy( 120);
final AbsoluteDate stop = t0.shiftedBy(1120);
ParameterDrivenDateIntervalDetector detector = new ParameterDrivenDateIntervalDetector("large-shift", start, stop).
final AbsoluteDate t0 = propagator.getInitialState().getDate();
final AbsoluteDate start = t0.shiftedBy( 120);
final AbsoluteDate stop = t0.shiftedBy(1120);
final double duration = stop.durationFrom(start);
final AbsoluteDate median = start.shiftedBy(0.5 * duration);
ParameterDrivenDateIntervalDetector detector = new ParameterDrivenDateIntervalDetector("large-shift", median, duration).
withMaxCheck(10.0).
withThreshold(1.0e-12).
withHandler(new ContinueOnEvent<>());
......@@ -123,6 +128,114 @@ public class ParameterDrivenDateIntervalDetectorTest {
}
@Test
public void testSelection() {
final AbsoluteDate t0 = propagator.getInitialState().getDate();
final AbsoluteDate start = t0.shiftedBy( 120);
final AbsoluteDate stop = t0.shiftedBy(1120);
ParameterDrivenDateIntervalDetector detector = new ParameterDrivenDateIntervalDetector("large-shift", start, stop).
withMaxCheck(10.0).
withThreshold(1.0e-12).
withHandler(new ContinueOnEvent<>());
Assert.assertFalse(detector.getStartDriver().isSelected());
Assert.assertFalse(detector.getStopDriver().isSelected());
Assert.assertFalse(detector.getMedianDriver().isSelected());
Assert.assertFalse(detector.getDurationDriver().isSelected());
// check all 16 possible configurations, changing one selection at a time
checkSelection(detector, detector.getDurationDriver(), true, false, false, false, true, false);
checkSelection(detector, detector.getMedianDriver(), true, false, false, true, true, false);
checkSelection(detector, detector.getDurationDriver(), false, false, false, true, false, false);
checkSelection(detector, detector.getStopDriver(), true, false, true, true, false, true);
checkSelection(detector, detector.getDurationDriver(), true, false, true, true, true, true);
checkSelection(detector, detector.getMedianDriver(), false, false, true, false, true, true);
checkSelection(detector, detector.getDurationDriver(), false, false, true, false, false, false);
checkSelection(detector, detector.getStartDriver(), true, true, true, false, false, false);
checkSelection(detector, detector.getDurationDriver(), true, true, true, false, true, true);
checkSelection(detector, detector.getMedianDriver(), true, true, true, true, true, true);
checkSelection(detector, detector.getDurationDriver(), false, true, true, true, false, true);
checkSelection(detector, detector.getStopDriver(), false, true, false, true, false, true);
checkSelection(detector, detector.getDurationDriver(), true, true, false, true, true, true);
checkSelection(detector, detector.getMedianDriver(), false, true, false, false, true, true);
checkSelection(detector, detector.getDurationDriver(), false, true, false, false, false, false);
checkSelection(detector, detector.getStartDriver(), false, false, false, false, false, false);
}
@Test
public void testStartStopToMedianDuration() {
final AbsoluteDate t0 = propagator.getInitialState().getDate();
final AbsoluteDate start = t0.shiftedBy( 120);
final AbsoluteDate stop = t0.shiftedBy(1120);
ParameterDrivenDateIntervalDetector detector = new ParameterDrivenDateIntervalDetector("large-shift", start, stop).
withMaxCheck(10.0).
withThreshold(1.0e-12).
withHandler(new ContinueOnEvent<>());
Assert.assertEquals( 0.0, detector.getStartDriver().getValue(), 1.0e-15);
Assert.assertEquals( 0.0, detector.getStopDriver().getValue(), 1.0e-15);
Assert.assertEquals( 0.0, detector.getMedianDriver().getValue(), 1.0e-15);
Assert.assertEquals(1000.0, detector.getDurationDriver().getValue(), 1.0e-15);
detector.getStartDriver().setSelected(true);
detector.getStartDriver().setValue(1.0);
Assert.assertEquals( 1.0, detector.getStartDriver().getValue(), 1.0e-15);
Assert.assertEquals( 0.0, detector.getStopDriver().getValue(), 1.0e-15);
Assert.assertEquals( 0.5, detector.getMedianDriver().getValue(), 1.0e-15);
Assert.assertEquals( 999.0, detector.getDurationDriver().getValue(), 1.0e-15);
detector.getStopDriver().setSelected(true);
detector.getStopDriver().setValue(10.0);
Assert.assertEquals( 1.0, detector.getStartDriver().getValue(), 1.0e-15);
Assert.assertEquals( 10.0, detector.getStopDriver().getValue(), 1.0e-15);
Assert.assertEquals( 5.5, detector.getMedianDriver().getValue(), 1.0e-15);
Assert.assertEquals(1009.0, detector.getDurationDriver().getValue(), 1.0e-15);
}
@Test
public void testMedianDurationToStartStop() {
final AbsoluteDate t0 = propagator.getInitialState().getDate();
final AbsoluteDate start = t0.shiftedBy( 120);
final AbsoluteDate stop = t0.shiftedBy(1120);
ParameterDrivenDateIntervalDetector detector = new ParameterDrivenDateIntervalDetector("large-shift", start, stop).
withMaxCheck(10.0).
withThreshold(1.0e-12).
withHandler(new ContinueOnEvent<>());
Assert.assertEquals( 0.0, detector.getStartDriver().getValue(), 1.0e-15);
Assert.assertEquals( 0.0, detector.getStopDriver().getValue(), 1.0e-15);
Assert.assertEquals( 0.0, detector.getMedianDriver().getValue(), 1.0e-15);
Assert.assertEquals(1000.0, detector.getDurationDriver().getValue(), 1.0e-15);
detector.getMedianDriver().setSelected(true);
detector.getMedianDriver().setValue(1.0);
Assert.assertEquals( 1.0, detector.getStartDriver().getValue(), 1.0e-15);
Assert.assertEquals( 1.0, detector.getStopDriver().getValue(), 1.0e-15);
Assert.assertEquals( 1.0, detector.getMedianDriver().getValue(), 1.0e-15);
Assert.assertEquals(1000.0, detector.getDurationDriver().getValue(), 1.0e-15);
detector.getDurationDriver().setSelected(true);
detector.getDurationDriver().setValue(900.0);
Assert.assertEquals( 51.0, detector.getStartDriver().getValue(), 1.0e-15);
Assert.assertEquals( -49.0, detector.getStopDriver().getValue(), 1.0e-15);
Assert.assertEquals( 1.0, detector.getMedianDriver().getValue(), 1.0e-15);
Assert.assertEquals( 900.0, detector.getDurationDriver().getValue(), 1.0e-15);
}
private void checkSelection(final ParameterDrivenDateIntervalDetector detector,
final ParameterDriver driver, final boolean selection, final boolean expectedStart,
final boolean expectedStop, final boolean expectedMedian,
final boolean expectedDuration, final boolean shouldFail) {
try {
driver.setSelected(selection);
if (shouldFail) {
Assert.fail("an exception should have been thrown");
}
} catch (OrekitException oe) {
Assert.assertEquals(OrekitMessages.INCONSISTENT_SELECTION, oe.getSpecifier());
}
Assert.assertEquals(selection, driver.isSelected());
Assert.assertEquals(expectedStart, detector.getStartDriver().isSelected());
Assert.assertEquals(expectedStop, detector.getStopDriver().isSelected());
Assert.assertEquals(expectedMedian, detector.getMedianDriver().isSelected());
Assert.assertEquals(expectedDuration, detector.getDurationDriver().isSelected());
}
@Before
public void setUp() {
Utils.setDataRoot("regular-data");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment