diff --git a/NOTICE.txt b/NOTICE.txt index a9e6b0b9b0d10f36a523deed8fec0b6a12c54896..054960b9e3e089b0618849114d3daf6d82d803f2 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -2,7 +2,7 @@ OREKIT Copyright 2002-2021 CS GROUP This product includes software developed by -CS GROUP (http://www.c-s.fr/) +CS GROUP (https://www.csgroup.eu/) This product includes software developed by Bruce R. Bowman (HQ AFSPC, Space Analysis Division) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index dfc1bd2120b9aabb41a726b2df30171d925c9bad..fb83a2f4f3a628d46d3c2f321aa6280839346dbb 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -21,15 +21,24 @@ </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> + <action dev="evan" type="update" issue="618"> + Fix supportedNames matching in ClasspathCrawler. Backwards incompatible. + </action> <action dev="bryan" type="fix" issue="828"> Fixed missing file types in SP3Parser. </action> <action dev="bryan" type="fix" issue="827"> Fixed time system used in SP3 files. </action> + <action dev="evan" type="fix" issue="685"> + Fix AnalyticalPropagator RESET_STATE when new state is null. + </action> <action dev="bryan" type="fix" issue="803"> Fixed parsing of clock values in SP3 files. </action> diff --git a/src/main/java/org/orekit/data/ClasspathCrawler.java b/src/main/java/org/orekit/data/ClasspathCrawler.java index e8d26f419b570072b0ca98c503d1eac125a8404c..b9bc36bb52ce5e36ba486ea917366883ca9c5aa1 100644 --- a/src/main/java/org/orekit/data/ClasspathCrawler.java +++ b/src/main/java/org/orekit/data/ClasspathCrawler.java @@ -127,8 +127,10 @@ public class ClasspathCrawler implements DataProvider { } else { + // match supported name against file name #618 + final String fileName = name.substring(name.lastIndexOf('/') + 1); + DataSource data = new DataSource(fileName, () -> classLoader.getResourceAsStream(name)); // apply all registered filters - DataSource data = new DataSource(name, () -> classLoader.getResourceAsStream(name)); data = manager.getFiltersManager().applyRelevantFilters(data); if (supported.matcher(data.getName()).matches()) { diff --git a/src/main/java/org/orekit/errors/OrekitMessages.java b/src/main/java/org/orekit/errors/OrekitMessages.java index a1e1cdd42f0a48edc6a4dd65d992885fe902dde9..e72617a1b10a00db6f398ea1765e3ea7b2cd7ac2 100644 --- a/src/main/java/org/orekit/errors/OrekitMessages.java +++ b/src/main/java/org/orekit/errors/OrekitMessages.java @@ -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 diff --git a/src/main/java/org/orekit/propagation/analytical/AbstractAnalyticalPropagator.java b/src/main/java/org/orekit/propagation/analytical/AbstractAnalyticalPropagator.java index bd644b549d13c2f3af99dc0ec8875cf050f950c7..1ab7adc4476f96f02167e34bdf3c1a3592109f4a 100644 --- a/src/main/java/org/orekit/propagation/analytical/AbstractAnalyticalPropagator.java +++ b/src/main/java/org/orekit/propagation/analytical/AbstractAnalyticalPropagator.java @@ -275,10 +275,8 @@ public abstract class AbstractAnalyticalPropagator extends AbstractPropagator { // some event handler has triggered changes that // invalidate the derivatives, we need to recompute them final SpacecraftState resetState = occurrence.getNewState(); - if (resetState != null) { - resetIntermediateState(resetState, interpolator.isForward()); - return resetState; - } + resetIntermediateState(resetState, interpolator.isForward()); + return resetState; } // at this point action == Action.CONTINUE or Action.RESET_EVENTS diff --git a/src/main/java/org/orekit/propagation/analytical/FieldAbstractAnalyticalPropagator.java b/src/main/java/org/orekit/propagation/analytical/FieldAbstractAnalyticalPropagator.java index 5ce6ac59a5ecc0b997fc204e1fe7abc316d41446..3a3b1cda40f056c61d8bce0cd0ae9d658f99abc5 100644 --- a/src/main/java/org/orekit/propagation/analytical/FieldAbstractAnalyticalPropagator.java +++ b/src/main/java/org/orekit/propagation/analytical/FieldAbstractAnalyticalPropagator.java @@ -284,10 +284,8 @@ public abstract class FieldAbstractAnalyticalPropagator<T extends CalculusFieldE // some event handler has triggered changes that // invalidate the derivatives, we need to recompute them final FieldSpacecraftState<T> resetState = occurrence.getNewState(); - if (resetState != null) { - resetIntermediateState(resetState, interpolator.isForward()); - return resetState; - } + resetIntermediateState(resetState, interpolator.isForward()); + return resetState; } // at this point action == Action.CONTINUE or Action.RESET_EVENTS diff --git a/src/main/java/org/orekit/propagation/events/EventState.java b/src/main/java/org/orekit/propagation/events/EventState.java index 373db96c7c3cac7dae80f9b6e905c2b5587fb218..6be884d519e8de2ee1cbadd16efa84ccb418a2a8 100644 --- a/src/main/java/org/orekit/propagation/events/EventState.java +++ b/src/main/java/org/orekit/propagation/events/EventState.java @@ -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; @@ -149,8 +154,8 @@ public class EventState<T extends EventDetector> { */ private double g(final SpacecraftState s) { if (!s.getDate().equals(lastT)) { - lastT = s.getDate(); lastG = detector.g(s); + lastT = s.getDate(); } return lastG; } @@ -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 diff --git a/src/main/java/org/orekit/propagation/events/FieldEventState.java b/src/main/java/org/orekit/propagation/events/FieldEventState.java index 50d012231112ede380c4f47c17358ab72ca2c920..9c60000405a5c572089d5cc34b8dccc87572eb4c 100644 --- a/src/main/java/org/orekit/propagation/events/FieldEventState.java +++ b/src/main/java/org/orekit/propagation/events/FieldEventState.java @@ -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 diff --git a/src/main/java/org/orekit/propagation/events/handlers/FieldRecordAndContinue.java b/src/main/java/org/orekit/propagation/events/handlers/FieldRecordAndContinue.java index 750af72be4304325038666d1921b53abfa4ad7b2..9908320f42eaad9adbc21006fae277e197da34e6 100644 --- a/src/main/java/org/orekit/propagation/events/handlers/FieldRecordAndContinue.java +++ b/src/main/java/org/orekit/propagation/events/handlers/FieldRecordAndContinue.java @@ -158,10 +158,4 @@ public class FieldRecordAndContinue return Action.CONTINUE; } - @Override - public FieldSpacecraftState<E> resetState(final T detector, - final FieldSpacecraftState<E> oldState) { - return null; - } - } diff --git a/src/main/java/org/orekit/propagation/events/handlers/RecordAndContinue.java b/src/main/java/org/orekit/propagation/events/handlers/RecordAndContinue.java index 2db7c7e7cf738be8cd33030aaf8644bd5a534cba..9983b6e9203e13620610a2657ad9fb58693dfe52 100644 --- a/src/main/java/org/orekit/propagation/events/handlers/RecordAndContinue.java +++ b/src/main/java/org/orekit/propagation/events/handlers/RecordAndContinue.java @@ -158,10 +158,4 @@ public class RecordAndContinue<T extends EventDetector> return Action.CONTINUE; } - @Override - public SpacecraftState resetState(final T detector, - final SpacecraftState oldState) { - return null; - } - } diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_da.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_da.utf8 index 5ea213f732787d0529be6595f3620c21f08a9238..7e51cce2344368d144622841a1373d21a8184e40 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_da.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_da.utf8 @@ -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> diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_de.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_de.utf8 index a0695cadffebaba7d86d3bffecbd01967781e435..1b08abfe5cee72e80bc14e11eaf6c3420f3bca5f 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_de.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_de.utf8 @@ -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> diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_el.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_el.utf8 index 3afdbba0e326ef3ec1c13eff24310f01c46ca51d..9ff2b28eb8160514ab266aaace6be182d6b9ea31 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_el.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_el.utf8 @@ -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> diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_en.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_en.utf8 index 03165e20a6fa6a50a326a50b42011fa06ab3de27..09c73066d47786856d6b56d2421c149c524ba93e 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_en.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_en.utf8 @@ -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}) diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_es.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_es.utf8 index e88a52d88342ccf69ac79f63d25989c524f8c882..f8185c9c4effc31f5777dd26d57a625afce0fdfe 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_es.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_es.utf8 @@ -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}) diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_fr.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_fr.utf8 index c476a311dc40b030d143131517bf3026458d7537..24a70b4ea33f87e4d56687707e7213309e3a555d 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_fr.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_fr.utf8 @@ -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}) diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_gl.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_gl.utf8 index 7a1de434968652d2b84e61bea09c60e60a2a5af6..b318e32c6dc8f145e870d2f27aec787dd42a2cf7 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_gl.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_gl.utf8 @@ -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> diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_it.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_it.utf8 index 52ec1e9121cbb88f68ac09205ab3ac0e1c105c71..4f09eef46ec6af1ce026378724204d9eda8af1a4 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_it.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_it.utf8 @@ -657,9 +657,6 @@ UNEXPECTED_FORMAT_FOR_ILRS_FILE = Inaspettato formato del file. Dovrebbe essere # Invalid range indicator {0} in CRD file header INVALID_RANGE_INDICATOR_IN_CRD_FILE = L'' intestazione del file CDR contiene un indicatore di intervallo {0} non valido -# Unexpected end of CRD file (after line {0}) -CRD_UNEXPECTED_END_OF_FILE = <MISSING TRANSLATION> - # end of encoded message reached END_OF_ENCODED_MESSAGE = è stata raggiunta la fine del messaggio @@ -711,6 +708,7 @@ MOUNPOINT_ALREADY_CONNECTED = il mount point {0} è già connesso # missing header from {0}: {1} MISSING_HEADER = header mancante in {0}: {1} +# Unexpected end of CRD file (after line {0}) CRD_UNEXPECTED_END_OF_FILE = Inattesa fine del file CRD alla linea {0} # {0} is not a valid international designator @@ -730,3 +728,6 @@ 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> diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_no.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_no.utf8 index e72b94c68e0020057c339cfb8d93ef73b41b6101..803c7a6f164aac6bd99c9287328586c1bcda8373 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_no.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_no.utf8 @@ -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> + diff --git a/src/main/resources/assets/org/orekit/localization/OrekitMessages_ro.utf8 b/src/main/resources/assets/org/orekit/localization/OrekitMessages_ro.utf8 index 8a4ce8eb13f116b74effcc2f3ded553b86a5f8d3..3f741941edae88847070a1daeb87ef76eff101e6 100644 --- a/src/main/resources/assets/org/orekit/localization/OrekitMessages_ro.utf8 +++ b/src/main/resources/assets/org/orekit/localization/OrekitMessages_ro.utf8 @@ -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> diff --git a/src/site/markdown/architecture/propagation.md b/src/site/markdown/architecture/propagation.md index 450447aa4e8aa2cfdfc0c135370bb3c948a8679e..60ceb30a002af5f5506e78187043577ec72942f3 100644 --- a/src/site/markdown/architecture/propagation.md +++ b/src/site/markdown/architecture/propagation.md @@ -37,7 +37,7 @@ intermediate states between the initial time and propagation target time, or it can provide only the final state. * intermediate states: In order to get intermediate states, users need to register - some custom object implementation the `OrekitStepHandler` or `OrekitFixedStephHandler` + some custom object implementation of the `OrekitStepHandler` or `OrekitFixedStephHandler` interfaces to the propagator before running it. As the propagator computes the evolution of spacecraft state, it performs some internal time loops and will call these step handlers at each finalized step. Users often use this mode with only a single @@ -53,16 +53,16 @@ it can provide only the final state. time representing the next small time step. There is no limitation on the number of step handlers that can be registered to a propagator. -Step handlers. Each propagator contains a multiplexer that can accept several step handlers. +Each propagator contains a multiplexer that can accept several step handlers. Step handlers can be either of `OrekitFixedStepHandler` type, which will be called at regular time intervals and fed with a single `SpacecraftState`, or they can be of `OrekitStepHandler` type, which will be called when the propagator accepts one step according to its internal time loop -and fed with an `OrekitStepInterpolator` that is valid throughout the step, hence providing -dense output. The following class diagram shows this architecture. +(time steps durection can vary in this case) and fed with an `OrekitStepInterpolator` that is valid +throughout the step, hence providing dense output. The following class diagram shows this architecture.  -Orekit uses internally this mechanism to provide some important features with specialized +Orekit uses this mechanism internally to provide some important features with specialized internal step handlers. The following class diagram shows for example that the `EphemerisGenerator` that can be requested from a propagator is based on a step handler that will store all intermediate steps during the propagation. Ephemeris generation from a propagator is used when the user needs @@ -95,7 +95,7 @@ intended to display progress for the user if computation is expected to be long.  The next sequence diagram shows a case where users want to control the time loop tightly -from within their application. In this case, the step handlers multiplexer is cleared and +from within their application. In this case, the step handlers multiplexer is cleared, the propagator is called multiple time, and returns states at requested target times. [without step handlers sequence diagram](../images/design/without-step-handlers-sequence-diagram.png) @@ -108,7 +108,7 @@ not the recommended way to use propagation. The recommended way is to register step handlers and call the propagation just once with the final time of the study as the target time and letting the propagator perform the time loop. It is -very simple to use and allow user to get rid of concerns about synchronizing force models, +very simple to use and allows users to get rid of concerns about synchronizing force models, file output, discrete events. All these parts are handled separately in different user code parts, and Orekit takes care of all management. From a user point of view, using step handler lead to much simpler code to maintain with smaller independent parts. Another important point is diff --git a/src/test/java/org/orekit/data/ClasspathCrawlerTest.java b/src/test/java/org/orekit/data/ClasspathCrawlerTest.java index eb253c02ae36fa1add416c80555644bb477549ae..72af518e6fbb0d1b913006ab75ec9793cbdb92d7 100644 --- a/src/test/java/org/orekit/data/ClasspathCrawlerTest.java +++ b/src/test/java/org/orekit/data/ClasspathCrawlerTest.java @@ -53,7 +53,7 @@ public class ClasspathCrawlerTest { CountingLoader crawler = new CountingLoader(); new ClasspathCrawler("compressed-data/UTC-TAI.history.gz", "compressed-data/eopc04_08_IAU2000.00.gz", - "compressed-data/eopc04_08_IAU2000.02.gz").feed(Pattern.compile(".*/eopc04.*"), + "compressed-data/eopc04_08_IAU2000.02.gz").feed(Pattern.compile(".*eopc04.*"), crawler, DataContext.getDefault().getDataProvidersManager()); Assert.assertEquals(2, crawler.getCount()); @@ -96,6 +96,24 @@ public class ClasspathCrawlerTest { } } + /** + * Check that only the file name portion is matched so that ^ works as expected with + * other crawlers. See #618. + */ + @Test + public void testMatchesFileName618() { + CountingLoader crawler = new CountingLoader(); + new ClasspathCrawler( + "regular-data/UTC-TAI.history", + "compressed-data/UTC-TAI.history.gz", + "no-data/dummy.txt" + ).feed( + Pattern.compile("^UTC-TAI.history$"), + crawler, + DataContext.getDefault().getDataProvidersManager()); + Assert.assertEquals(2, crawler.getCount()); + } + private static class CountingLoader implements DataLoader { private int count = 0; public boolean stillAcceptsData() { diff --git a/src/test/java/org/orekit/errors/OrekitMessagesTest.java b/src/test/java/org/orekit/errors/OrekitMessagesTest.java index 6e6ff91de5ec6b538dc773cccbe4ac92730e6b02..a0489d15eadbed1289bb890fe13683523e6f957c 100644 --- a/src/test/java/org/orekit/errors/OrekitMessagesTest.java +++ b/src/test/java/org/orekit/errors/OrekitMessagesTest.java @@ -30,7 +30,7 @@ public class OrekitMessagesTest { @Test public void testMessageNumber() { - Assert.assertEquals(243, OrekitMessages.values().length); + Assert.assertEquals(244, OrekitMessages.values().length); } @Test diff --git a/src/test/java/org/orekit/propagation/events/CloseEventsAbstractTest.java b/src/test/java/org/orekit/propagation/events/CloseEventsAbstractTest.java index 405dc74fe60566fb428e84d2a24036acbbe1607e..e9944ef9599ad5f6d656e84da8a164a5474c3bc1 100644 --- a/src/test/java/org/orekit/propagation/events/CloseEventsAbstractTest.java +++ b/src/test/java/org/orekit/propagation/events/CloseEventsAbstractTest.java @@ -1084,6 +1084,34 @@ public abstract class CloseEventsAbstractTest { Assert.assertEquals(2, stepHandler.interpolators.size()); } + /** + * Test {@link EventHandler#resetState(EventDetector, SpacecraftState)} returns {@code + * null}. + */ + @Test + public void testEventCausedByDerivativesReset() { + // setup + TimeDetector detectorA = new TimeDetector(15.0) + .withHandler(new Handler<TimeDetector>(Action.RESET_STATE){ + @Override + public SpacecraftState resetState(TimeDetector d, SpacecraftState s) { + return null; + } + }) + .withMaxCheck(10) + .withThreshold(1e-6); + Propagator propagator = getPropagator(10); + propagator.addEventDetector(detectorA); + + try { + // action + propagator.propagate(epoch.shiftedBy(20.0)); + Assert.fail("Expected Exception"); + } catch (NullPointerException e) { + // expected + } + } + /* The following tests are copies of the above tests, except that they propagate in * the reverse direction and all the signs on the time values are negated. @@ -2061,6 +2089,34 @@ public abstract class CloseEventsAbstractTest { Assert.assertEquals(2, stepHandler.interpolators.size()); } + /** + * Test {@link EventHandler#resetState(EventDetector, SpacecraftState)} returns {@code + * null}. + */ + @Test + public void testEventCausedByDerivativesResetReverse() { + // setup + TimeDetector detectorA = new TimeDetector(-15.0) + .withHandler(new Handler<TimeDetector>(Action.RESET_STATE){ + @Override + public SpacecraftState resetState(TimeDetector d, SpacecraftState s) { + return null; + } + }) + .withMaxCheck(10) + .withThreshold(1e-6); + Propagator propagator = getPropagator(10); + propagator.addEventDetector(detectorA); + + try { + // action + propagator.propagate(epoch.shiftedBy(-20.0)); + Assert.fail("Expected Exception"); + } catch (NullPointerException e) { + // expected + } + } + /* utility classes and methods */ diff --git a/src/test/java/org/orekit/propagation/events/EventDetectorTest.java b/src/test/java/org/orekit/propagation/events/EventDetectorTest.java index e6fbfed33a0b579cd3c8bed23332b14a0a535de6..fe427feeb8881219bf1dbdc4e24e7453b3473a24 100644 --- a/src/test/java/org/orekit/propagation/events/EventDetectorTest.java +++ b/src/test/java/org/orekit/propagation/events/EventDetectorTest.java @@ -300,7 +300,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()); } } diff --git a/src/test/java/org/orekit/propagation/events/FieldCloseEventsAbstractTest.java b/src/test/java/org/orekit/propagation/events/FieldCloseEventsAbstractTest.java index 76c2ed2b922bfebe9960c3360cc84d3eacf56eb4..330278bd5c3e3b9963582109c28e538a30a10b78 100644 --- a/src/test/java/org/orekit/propagation/events/FieldCloseEventsAbstractTest.java +++ b/src/test/java/org/orekit/propagation/events/FieldCloseEventsAbstractTest.java @@ -35,6 +35,8 @@ import org.orekit.orbits.FieldKeplerianOrbit; import org.orekit.orbits.PositionAngle; import org.orekit.propagation.FieldPropagator; import org.orekit.propagation.FieldSpacecraftState; +import org.orekit.propagation.SpacecraftState; +import org.orekit.propagation.events.handlers.EventHandler; import org.orekit.propagation.events.handlers.FieldEventHandler; import org.orekit.propagation.events.handlers.FieldRecordAndContinue; import org.orekit.propagation.events.handlers.FieldRecordAndContinue.Event; @@ -1176,6 +1178,35 @@ public abstract class FieldCloseEventsAbstractTest<T extends CalculusFieldElemen Assert.assertEquals(2, stepHandler.interpolators.size()); } + /** + * Test {@link EventHandler#resetState(EventDetector, SpacecraftState)} returns {@code + * null}. + */ + @Test + public void testEventCausedByDerivativesReset() { + // setup + TimeDetector detectorA = new TimeDetector(15.0) + .withHandler(new Handler<TimeDetector>(Action.RESET_STATE){ + @Override + public FieldSpacecraftState<T> resetState(TimeDetector d, + FieldSpacecraftState<T> s) { + return null; + } + }) + .withMaxCheck(v(10)) + .withThreshold(v(1e-6)); + FieldPropagator<T> propagator = getPropagator(10); + propagator.addEventDetector(detectorA); + + try { + // action + propagator.propagate(epoch.shiftedBy(20.0)); + Assert.fail("Expected Exception"); + } catch (NullPointerException e) { + // expected + } + } + /* The following tests are copies of the above tests, except that they propagate in * the reverse direction and all the signs on the time values are negated. @@ -2275,6 +2306,35 @@ public abstract class FieldCloseEventsAbstractTest<T extends CalculusFieldElemen Assert.assertEquals(2, stepHandler.interpolators.size()); } + /** + * Test {@link EventHandler#resetState(EventDetector, SpacecraftState)} returns {@code + * null}. + */ + @Test + public void testEventCausedByDerivativesResetReverse() { + // setup + TimeDetector detectorA = new TimeDetector(-15.0) + .withHandler(new Handler<TimeDetector>(Action.RESET_STATE){ + @Override + public FieldSpacecraftState<T> resetState(TimeDetector d, + FieldSpacecraftState<T> s) { + return null; + } + }) + .withMaxCheck(v(10)) + .withThreshold(v(1e-6)); + FieldPropagator<T> propagator = getPropagator(10); + propagator.addEventDetector(detectorA); + + try { + // action + propagator.propagate(epoch.shiftedBy(-20.0)); + Assert.fail("Expected Exception"); + } catch (NullPointerException e) { + // expected + } + } + /* utility classes and methods */ diff --git a/src/test/java/org/orekit/propagation/events/FieldEventDetectorTest.java b/src/test/java/org/orekit/propagation/events/FieldEventDetectorTest.java index 7fcbbded1d90738bb9cfa6c40d6a694ddf806690..82e45ecef963c2f40e000b6fa92991b0ff9e3f3e 100644 --- a/src/test/java/org/orekit/propagation/events/FieldEventDetectorTest.java +++ b/src/test/java/org/orekit/propagation/events/FieldEventDetectorTest.java @@ -370,7 +370,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()); } }