From 049902bf550a1f66e798464a5acb928933fa9b94 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Wed, 24 Aug 2016 10:21:25 +0200 Subject: [PATCH] Added more error detection to parameters estimation. --- .../java/org/orekit/rugged/api/Rugged.java | 18 +++-- .../orekit/rugged/errors/RuggedMessages.java | 2 + .../org/orekit/rugged/RuggedMessages_de.utf8 | 6 ++ .../org/orekit/rugged/RuggedMessages_en.utf8 | 7 +- .../org/orekit/rugged/RuggedMessages_es.utf8 | 6 ++ .../org/orekit/rugged/RuggedMessages_fr.utf8 | 7 +- .../org/orekit/rugged/RuggedMessages_gl.utf8 | 7 +- .../org/orekit/rugged/RuggedMessages_it.utf8 | 7 +- .../org/orekit/rugged/RuggedMessages_no.utf8 | 6 ++ .../org/orekit/rugged/RuggedMessages_ro.utf8 | 6 ++ .../org/orekit/rugged/api/RuggedTest.java | 70 +++++++++++++++++-- .../rugged/errors/RuggedMessagesTest.java | 2 +- 12 files changed, 127 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index 8b273060..3609513c 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -713,7 +713,7 @@ public class Rugged { * <p> * Before using this method, the {@link ParameterDriver viewing model * parameters} retrieved by calling the {@link - * LineSensor#getExtendedParametersDrivers() getExtendedParametersDrivers()} + * LineSensor#getParametersDrivers() getParametersDrivers()} * method on the desired sensors must be configured. The parameters that should * be estimated must have their {@link ParameterDriver#setSelected(boolean) * selection status} set to {@link true} whereas the parameters that should retain @@ -730,11 +730,11 @@ public class Rugged { * </p> * <p> * The estimated parameters can be retrieved after the method completes by calling - * again the {@link LineSensor#getExtendedParametersDrivers() getExtendedParametersDrivers()} + * again the {@link LineSensor#getParametersDrivers() getParametersDrivers()} * method on the desired sensors and checking the updated values of the parameters. * In fact, as the values of the parameters are already updated by this method, if - * wants to use the updated values immediately to perform new direct/inverse - * locations they can do so without looking at the parameters: the viewing models + * users want to use the updated values immediately to perform new direct/inverse + * locations, they can do so without looking at the parameters: the viewing models * are already aware of the updated parameters. * </p> * @param references reference mappings between sensors pixels and ground point that @@ -744,7 +744,8 @@ public class Rugged { * normalized parameters (dimensionless, related to parameters scales) * @return optimum of the least squares problem * @exception RuggedException if several parameters with the same name exist, - * or if parameters cannot be estimated (too few measurements, ill-conditioned problem ...) + * if no parameters have been selected for estimation, or if parameters cannot be + * estimated (too few measurements, ill-conditioned problem ...) */ public Optimum estimateFreeParameters(final Collection<SensorToGroundMapping> references, final int maxEvaluations, @@ -758,6 +759,9 @@ public class Rugged { } final DSGenerator generator = createGenerator(selectedSensors); final List<ParameterDriver> selected = generator.getSelected(); + if (selected.isEmpty()) { + throw new RuggedException(RuggedMessages.NO_PARAMETERS_SELECTED); + } // get start point (as a normalized value) final double[] start = new double[selected.size()]; @@ -770,6 +774,9 @@ public class Rugged { for (final SensorToGroundMapping reference : references) { n += reference.getMappings().size(); } + if (n == 0) { + throw new RuggedException(RuggedMessages.NO_REFERENCE_MAPPINGS); + } final double[] target = new double[2 * n]; double min = Double.POSITIVE_INFINITY; double max = Double.NEGATIVE_INFINITY; @@ -905,6 +912,7 @@ public class Rugged { throw new RuggedExceptionWrapper(new RuggedException(RuggedMessages.DUPLICATED_PARAMETER_NAME, driver.getName())); } + names.add(driver.getName()); }); } diff --git a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java index a0c453b1..0b021db9 100644 --- a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java +++ b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java @@ -75,6 +75,8 @@ public enum RuggedMessages implements Localizable { ABERRATION_OF_LIGHT_CORRECTION_REDEFINED("aberration of light correction redefined, line {0}, file {1}: {2}"), TILE_ALREADY_DEFINED("tile {0} already defined, line {1}, file {2}: {3}"), UNKNOWN_TILE("unknown tile {0}, line {1}, file {2}: {3}"), + NO_PARAMETERS_SELECTED("no parameters have been selected for estimation"), + NO_REFERENCE_MAPPINGS("no reference mappings for parameters estimation"), DUPLICATED_PARAMETER_NAME("a different parameter with name {0} already exists"); // CHECKSTYLE: resume JavadocVariable check diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 index 9938abc6..3982b7c8 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 @@ -72,6 +72,12 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION> # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = <MISSING TRANSLATION> + +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = <MISSING TRANSLATION> + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = <MISSING TRANSLATION> # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 index b3604412..75e9cab1 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 @@ -73,6 +73,11 @@ TILE_ALREADY_DEFINED = tile {0} already defined, line {1}, file {2}: {3} # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = unknown tile {0}, line {1}, file {2}: {3} +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = no parameters have been selected for estimation + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = no reference mappings for parameters estimation + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = a different parameter with name {0} already exists - diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 index 25642997..113d92b8 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 @@ -73,5 +73,11 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION> # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = <MISSING TRANSLATION> +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = <MISSING TRANSLATION> + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = <MISSING TRANSLATION> + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 index 969170f1..9854f68f 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 @@ -73,6 +73,11 @@ TILE_ALREADY_DEFINED = tuile {0} déjà définie ligne {1} du fichier {2}: {3} # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = tuile {0} inconnue ligne {1} du fichier {2}: {3} +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = aucun paramètre n''a été sélectionné pour être estimé + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = aucune projection de référence pour l''estimation des paramètres + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = il existe déjà un autre paramètre nommé {0} - diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 index 27bf9ece..434a10aa 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 @@ -73,6 +73,11 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION> # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = <MISSING TRANSLATION> +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = <MISSING TRANSLATION> + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = <MISSING TRANSLATION> + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = <MISSING TRANSLATION> - diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 index 569c8374..90dd36c0 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 @@ -73,6 +73,11 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION> # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = <MISSING TRANSLATION> +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = <MISSING TRANSLATION> + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = <MISSING TRANSLATION> + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = <MISSING TRANSLATION> - diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 index f94c208b..ccca6d63 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 @@ -73,5 +73,11 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION> # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = <MISSING TRANSLATION> +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = <MISSING TRANSLATION> + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = <MISSING TRANSLATION> + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 index 72263acf..7aa5bbb8 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 @@ -73,5 +73,11 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION> # unknown tile {0}, line {1}, file {2}: {3} UNKNOWN_TILE = <MISSING TRANSLATION> +# no parameters have been selected for estimation +NO_PARAMETERS_SELECTED = <MISSING TRANSLATION> + +# no reference mappings for parameters estimation +NO_REFERENCE_MAPPINGS = <MISSING TRANSLATION> + # a different parameter with name {0} already exists DUPLICATED_PARAMETER_NAME = <MISSING TRANSLATION> diff --git a/src/test/java/org/orekit/rugged/api/RuggedTest.java b/src/test/java/org/orekit/rugged/api/RuggedTest.java index f882dd9c..c91bd666 100644 --- a/src/test/java/org/orekit/rugged/api/RuggedTest.java +++ b/src/test/java/org/orekit/rugged/api/RuggedTest.java @@ -26,6 +26,7 @@ import java.net.URISyntaxException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -1229,6 +1230,62 @@ public class RuggedTest { } } + @Test + public void testNoParametersSelected() + throws OrekitException { + try { + Rugged perfect = createParameterEstimationContext(2000, false, false).build(); + perfect.estimateFreeParameters(Collections.singletonList(new SensorToGroundMapping("line")), + 100, 1.0e-3); + Assert.fail("an exception should have been thrown"); + } catch (RuggedException re) { + Assert.assertEquals(RuggedMessages.NO_PARAMETERS_SELECTED, re.getSpecifier()); + } + } + + @Test + public void testDuplicatedParameter() + throws OrekitException { + try { + TimeDependentLOS los = + TestUtils.createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, 0.1, 1000). + addTransform(new FixedRotation("pitch", Vector3D.MINUS_J, 0.0)).build(); + LineDatation lineDatation = new LinearLineDatation(AbsoluteDate.J2000_EPOCH, 50, 1.0 / 1.5e-3); + Rugged perfect = createParameterEstimationContext(2000, false, false). + addLineSensor(new LineSensor("other", lineDatation, Vector3D.ZERO, los)). + build(); + // the duplicated parameter is "pitch", it will be detected even despite only "roll" is estimated + perfect.getLineSensor("line"). + getParametersDrivers(). + filter(driver -> driver.getName().equals("roll")). + forEach(driver -> driver.setSelected(true)); + perfect.estimateFreeParameters(Arrays.asList(new SensorToGroundMapping("line"), + new SensorToGroundMapping("other")), + 100, 1.0e-3); + Assert.fail("an exception should have been thrown"); + } catch (RuggedException re) { + Assert.assertEquals(RuggedMessages.DUPLICATED_PARAMETER_NAME, re.getSpecifier()); + Assert.assertEquals("pitch", re.getParts()[0]); + } + } + + @Test + public void testNoReferenceMapping() + throws OrekitException { + try { + Rugged perfect = createParameterEstimationContext(2000, false, false).build(); + perfect.getLineSensor("line"). + getParametersDrivers(). + filter(driver -> driver.getName().equals("roll") || driver.getName().equals("pitch")). + forEach(driver -> driver.setSelected(true)); + perfect.estimateFreeParameters(Collections.singletonList(new SensorToGroundMapping("line")), + 100, 1.0e-3); + Assert.fail("an exception should have been thrown"); + } catch (RuggedException re) { + Assert.assertEquals(RuggedMessages.NO_REFERENCE_MAPPINGS, re.getSpecifier()); + } + } + @Test public void testViewingModelParametersEstimationWithoutCorrections() throws OrekitException, RuggedException { @@ -1277,7 +1334,7 @@ public class RuggedTest { // set up a perfect Rugged instance, with prescribed roll and pitch values Rugged perfect = createParameterEstimationContext(dimension, lightTimeCorrection, - aberrationOfLightCorrection); + aberrationOfLightCorrection).build(); perfect. getLineSensor("line"). getParametersDrivers(). @@ -1306,7 +1363,7 @@ public class RuggedTest { // with 0.0 roll and pitch values and estimating rool and pitch Rugged normal = createParameterEstimationContext(dimension, lightTimeCorrection, - aberrationOfLightCorrection); + aberrationOfLightCorrection).build(); normal. getLineSensor("line"). getParametersDrivers(). @@ -1344,9 +1401,9 @@ public class RuggedTest { } } - private Rugged createParameterEstimationContext(int dimension, - boolean lightTimeCorrection, - boolean aberrationOfLightCorrection) + private RuggedBuilder createParameterEstimationContext(int dimension, + boolean lightTimeCorrection, + boolean aberrationOfLightCorrection) throws OrekitException, RuggedException { try { @@ -1396,8 +1453,7 @@ public class RuggedTest { 2, AngularDerivativesFilter.USE_R). setLightTimeCorrection(lightTimeCorrection). setAberrationOfLightCorrection(aberrationOfLightCorrection). - addLineSensor(lineSensor). - build(); + addLineSensor(lineSensor); } catch (URISyntaxException e) { Assert.fail(e.getLocalizedMessage()); diff --git a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java index 62e411c5..0dd7a081 100644 --- a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java +++ b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java @@ -30,7 +30,7 @@ public class RuggedMessagesTest { @Test public void testMessageNumber() { - Assert.assertEquals(26, RuggedMessages.values().length); + Assert.assertEquals(28, RuggedMessages.values().length); } @Test -- GitLab