Commit 0440f78d authored by LUGAN's avatar LUGAN
Browse files

Help user to know which and when a detector fails

parent 06700482
......@@ -21,6 +21,9 @@
</properties>
<body>
<release version="11.0" date="TBD" description="TBD">
<action dev="anne-laure" type="update" issue="797">
Add information if a detector failed during propagation
</action>
<action dev="bryan" type="fix" issue="788" due-to="luc">
Fixed missing call to setMuCreated() in OemParser.
</action>
......
......@@ -322,7 +322,8 @@ public enum OrekitMessages implements Localizable {
UNKNOWN_UNIT("unknown unit {0}"),
INCOMPATIBLE_UNITS("units {0} and {1} are not compatible"),
MISSING_VELOCITY("missing velocity data"),
ATTEMPT_TO_GENERATE_MALFORMED_FILE("attempt to generate file {0} with a formatting error");
ATTEMPT_TO_GENERATE_MALFORMED_FILE("attempt to generate file {0} with a formatting error"),
FIND_ROOT("{0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})");
// CHECKSTYLE: resume JavadocVariable check
......
......@@ -24,7 +24,9 @@ import org.hipparchus.exception.MathRuntimeException;
import org.hipparchus.ode.events.Action;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.Precision;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitInternalError;
import org.orekit.errors.OrekitMessages;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.sampling.OrekitStepInterpolator;
import org.orekit.time.AbsoluteDate;
......@@ -47,6 +49,9 @@ import org.orekit.time.AbsoluteDate;
* @param <T> class type for the generic version
*/
public class EventState<T extends EventDetector> {
/** Format to be used to print double values. */
private static final String SCIENTIFIC_FORMAT = "%.3e";
/** Event detector. */
private T detector;
......@@ -299,50 +304,61 @@ public class EventState<T extends EventDetector> {
double loopG = ga;
while ((afterRootG == 0.0 || afterRootG > 0.0 == g0Positive) &&
strictlyAfter(afterRootT, tb)) {
if (loopG == 0.0) {
// ga == 0.0 and gb may or may not be 0.0
// handle the root at ta first
beforeRootT = loopT;
beforeRootG = loopG;
afterRootT = minTime(shiftedBy(beforeRootT, convergence), tb);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
} else {
// both non-zero, the usual case, use a root finder.
// time zero for evaluating the function f. Needs to be final
final AbsoluteDate fT0 = loopT;
final UnivariateFunction f = dt -> {
return g(interpolator.getInterpolatedState(fT0.shiftedBy(dt)));
};
// tb as a double for use in f
final double tbDouble = tb.durationFrom(fT0);
if (forward) {
final Interval interval =
solver.solveInterval(maxIterationCount, f, 0, tbDouble);
beforeRootT = fT0.shiftedBy(interval.getLeftAbscissa());
beforeRootG = interval.getLeftValue();
afterRootT = fT0.shiftedBy(interval.getRightAbscissa());
afterRootG = interval.getRightValue();
try {
if (loopG == 0.0) {
// ga == 0.0 and gb may or may not be 0.0
// handle the root at ta first
beforeRootT = loopT;
beforeRootG = loopG;
afterRootT = minTime(shiftedBy(beforeRootT, convergence), tb);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
} else {
final Interval interval =
solver.solveInterval(maxIterationCount, f, tbDouble, 0);
beforeRootT = fT0.shiftedBy(interval.getRightAbscissa());
beforeRootG = interval.getRightValue();
afterRootT = fT0.shiftedBy(interval.getLeftAbscissa());
afterRootG = interval.getLeftValue();
// both non-zero, the usual case, use a root finder.
// time zero for evaluating the function f. Needs to be final
final AbsoluteDate fT0 = loopT;
final UnivariateFunction f = dt -> {
return g(interpolator.getInterpolatedState(fT0.shiftedBy(dt)));
};
// tb as a double for use in f
final double tbDouble = tb.durationFrom(fT0);
if (forward) {
final Interval interval =
solver.solveInterval(maxIterationCount, f, 0, tbDouble);
beforeRootT = fT0.shiftedBy(interval.getLeftAbscissa());
beforeRootG = interval.getLeftValue();
afterRootT = fT0.shiftedBy(interval.getRightAbscissa());
afterRootG = interval.getRightValue();
} else {
final Interval interval =
solver.solveInterval(maxIterationCount, f, tbDouble, 0);
beforeRootT = fT0.shiftedBy(interval.getRightAbscissa());
beforeRootG = interval.getRightValue();
afterRootT = fT0.shiftedBy(interval.getLeftAbscissa());
afterRootG = interval.getLeftValue();
}
}
// tolerance is set to less than 1 ulp
// assume tolerance is 1 ulp
if (beforeRootT.equals(afterRootT)) {
afterRootT = nextAfter(afterRootT);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
}
// check loop is making some progress
check(forward && afterRootT.compareTo(beforeRootT) > 0 ||
!forward && afterRootT.compareTo(beforeRootT) < 0);
// setup next iteration
loopT = afterRootT;
loopG = afterRootG;
}
// tolerance is set to less than 1 ulp
// assume tolerance is 1 ulp
if (beforeRootT.equals(afterRootT)) {
afterRootT = nextAfter(afterRootT);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
catch (RuntimeException e) {
if (forward) {
throw new OrekitException(e, OrekitMessages.FIND_ROOT, detector, ta, String.format(SCIENTIFIC_FORMAT, ga), tb, String.format(SCIENTIFIC_FORMAT, gb), lastT,
String.format(SCIENTIFIC_FORMAT, lastG));
} else {
throw new OrekitException(e, OrekitMessages.FIND_ROOT, detector, tb, String.format(SCIENTIFIC_FORMAT, gb), ta, String.format(SCIENTIFIC_FORMAT, ga), lastT,
String.format(SCIENTIFIC_FORMAT, lastG));
}
}
// check loop is making some progress
check(forward && afterRootT.compareTo(beforeRootT) > 0 ||
!forward && afterRootT.compareTo(beforeRootT) < 0);
// setup next iteration
loopT = afterRootT;
loopG = afterRootG;
}
// figure out the result of root finding, and return accordingly
......
......@@ -26,7 +26,9 @@ import org.hipparchus.exception.MathRuntimeException;
import org.hipparchus.ode.events.Action;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.Precision;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitInternalError;
import org.orekit.errors.OrekitMessages;
import org.orekit.propagation.FieldSpacecraftState;
import org.orekit.propagation.sampling.FieldOrekitStepInterpolator;
import org.orekit.time.FieldAbsoluteDate;
......@@ -304,50 +306,59 @@ public class FieldEventState<D extends FieldEventDetector<T>, T extends Calculus
T loopG = ga;
while ((afterRootG.getReal() == 0.0 || afterRootG.getReal() > 0.0 == g0Positive) &&
strictlyAfter(afterRootT, tb)) {
if (loopG.getReal() == 0.0) {
// ga == 0.0 and gb may or may not be 0.0
// handle the root at ta first
beforeRootT = loopT;
beforeRootG = loopG;
afterRootT = minTime(shiftedBy(beforeRootT, convergence), tb);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
} else {
// both non-zero, the usual case, use a root finder.
// time zero for evaluating the function f. Needs to be final
final FieldAbsoluteDate<T> fT0 = loopT;
final UnivariateFunction f = dt -> {
return g(interpolator.getInterpolatedState(fT0.shiftedBy(dt))).getReal();
};
// tb as a double for use in f
final T tbDouble = tb.durationFrom(fT0);
if (forward) {
final Interval interval =
solver.solveInterval(maxIterationCount, f, 0, tbDouble.getReal());
beforeRootT = fT0.shiftedBy(interval.getLeftAbscissa());
beforeRootG = zero.add(interval.getLeftValue());
afterRootT = fT0.shiftedBy(interval.getRightAbscissa());
afterRootG = zero.add(interval.getRightValue());
try {
if (loopG.getReal() == 0.0) {
// ga == 0.0 and gb may or may not be 0.0
// handle the root at ta first
beforeRootT = loopT;
beforeRootG = loopG;
afterRootT = minTime(shiftedBy(beforeRootT, convergence), tb);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
} else {
final Interval interval =
solver.solveInterval(maxIterationCount, f, tbDouble.getReal(), 0);
beforeRootT = fT0.shiftedBy(interval.getRightAbscissa());
beforeRootG = zero.add(interval.getRightValue());
afterRootT = fT0.shiftedBy(interval.getLeftAbscissa());
afterRootG = zero.add(interval.getLeftValue());
// both non-zero, the usual case, use a root finder.
// time zero for evaluating the function f. Needs to be final
final FieldAbsoluteDate<T> fT0 = loopT;
final UnivariateFunction f = dt -> {
return g(interpolator.getInterpolatedState(fT0.shiftedBy(dt))).getReal();
};
// tb as a double for use in f
final T tbDouble = tb.durationFrom(fT0);
if (forward) {
final Interval interval =
solver.solveInterval(maxIterationCount, f, 0, tbDouble.getReal());
beforeRootT = fT0.shiftedBy(interval.getLeftAbscissa());
beforeRootG = zero.add(interval.getLeftValue());
afterRootT = fT0.shiftedBy(interval.getRightAbscissa());
afterRootG = zero.add(interval.getRightValue());
} else {
final Interval interval =
solver.solveInterval(maxIterationCount, f, tbDouble.getReal(), 0);
beforeRootT = fT0.shiftedBy(interval.getRightAbscissa());
beforeRootG = zero.add(interval.getRightValue());
afterRootT = fT0.shiftedBy(interval.getLeftAbscissa());
afterRootG = zero.add(interval.getLeftValue());
}
}
// tolerance is set to less than 1 ulp
// assume tolerance is 1 ulp
if (beforeRootT.equals(afterRootT)) {
afterRootT = nextAfter(afterRootT);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
}
// check loop is making some progress
check(forward && afterRootT.compareTo(beforeRootT) > 0 ||
!forward && afterRootT.compareTo(beforeRootT) < 0);
// setup next iteration
loopT = afterRootT;
loopG = afterRootG;
}
// tolerance is set to less than 1 ulp
// assume tolerance is 1 ulp
if (beforeRootT.equals(afterRootT)) {
afterRootT = nextAfter(afterRootT);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
catch (RuntimeException e) {
if (forward) {
throw new OrekitException(e, OrekitMessages.FIND_ROOT, detector, ta, ga, tb, gb, lastT, lastG);
} else {
throw new OrekitException(e, OrekitMessages.FIND_ROOT, detector, tb, gb, ta, ga, lastT, lastG);
}
}
// check loop is making some progress
check(forward && afterRootT.compareTo(beforeRootT) > 0 ||
!forward && afterRootT.compareTo(beforeRootT) < 0);
// setup next iteration
loopT = afterRootT;
loopG = afterRootG;
}
// figure out the result of root finding, and return accordingly
......
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = missing velocity data
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = attempt to generate file {0} with a formatting error
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = {0} ha fallado buscando una solución entre {1} (g={2}) y {3} (g={4})\nÚltima iteración en {5} (g={6})
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = données de vitesse manquantes
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = tentative de génération du fichier {0} avec une erreur de format
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = {0} n''a pas réussi à trouver une solution entre {1} (g={2}) et {3} (g={4})\nLa dernière itération était à {5} (g={6})
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -730,3 +730,7 @@ MISSING_VELOCITY = informazioni mancanti su velocità
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -728,3 +728,7 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -728,3 +728,6 @@ MISSING_VELOCITY = <MISSING TRANSLATION>
# attempt to generate file {0} with a formatting error
ATTEMPT_TO_GENERATE_MALFORMED_FILE = <MISSING TRANSLATION>
# {0} failed to find root between {1} (g={2}) and {3} (g={4})\nLast iteration at {5} (g={6})
FIND_ROOT = <MISSING TRANSLATION>
......@@ -30,7 +30,7 @@ public class OrekitMessagesTest {
@Test
public void testMessageNumber() {
Assert.assertEquals(243, OrekitMessages.values().length);
Assert.assertEquals(244, OrekitMessages.values().length);
}
@Test
......
......@@ -299,7 +299,8 @@ public class EventDetectorTest {
k.propagate(initialDate.shiftedBy(Constants.JULIAN_YEAR));
Assert.fail("an exception should have been thrown");
} catch (OrekitException oe) {
Assert.assertSame(dummyCause, oe.getCause());
Assert.assertSame(OrekitException.class, oe.getClass());
Assert.assertSame(dummyCause, oe.getCause().getCause());
}
}
......
......@@ -369,7 +369,8 @@ public class FieldEventDetectorTest {
k.propagate(initialDate.shiftedBy(Constants.JULIAN_YEAR));
Assert.fail("an exception should have been thrown");
} catch (OrekitException oe) {
Assert.assertSame(dummyCause, oe.getCause());
Assert.assertSame(OrekitException.class, oe.getClass());
Assert.assertSame(dummyCause, oe.getCause().getCause());
}
}
......
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