From e3adf730660d81ebbac83feb0c383ec5ee933359 Mon Sep 17 00:00:00 2001 From: gprat <guylaine.prat@csgroup.eu> Date: Tue, 14 Jun 2022 15:09:08 +0200 Subject: [PATCH] Custom margin for atmospheric refraction; made exception message clearer Fixes #391 --- .../java/org/orekit/rugged/api/Rugged.java | 28 +++-- .../orekit/rugged/errors/RuggedMessages.java | 3 +- .../AtmosphericComputationParameters.java | 40 ++++++ .../refraction/AtmosphericRefraction.java | 18 ++- .../org/orekit/rugged/RuggedMessages_da.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_de.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_en.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_es.utf8 | 4 + .../org/orekit/rugged/RuggedMessages_fr.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_gl.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_it.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_no.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_ro.utf8 | 3 + .../org/orekit/rugged/api/RuggedTest.java | 15 +++ .../rugged/errors/RuggedMessagesTest.java | 2 +- .../refraction/AtmosphericRefractionTest.java | 114 +++++++++++++++++- .../AtmosphericRefractionExamples.java | 7 ++ 17 files changed, 239 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index d86e69c0..0a283fc5 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -66,9 +66,6 @@ public class Rugged { /** Maximum number of evaluations for crossing algorithms. */ private static final int MAX_EVAL = 50; - /** Margin for computation of inverse location with atmospheric refraction correction. */ - private static final double INVLOC_MARGIN = 0.8; - /** Threshold for pixel convergence in fixed point method * (for inverse location with atmospheric refraction correction). */ private static final double PIXEL_CV_THRESHOLD = 1.e-4; @@ -730,8 +727,10 @@ public class Rugged { if (sp0 == null) { // In order for the dump to end nicely DumpManager.endNicely(); - // Impossible to find the point in the given min line and max line (without atmosphere) - throw new RuggedException(RuggedMessages.INVALID_RANGE_FOR_LINES, minLine, maxLine, ""); + + // Impossible to find the sensor pixel in the given range lines (without atmosphere) + final String info = "in given range lines (with atmospheric refraction) between lines" + minLine + " and " + maxLine; + throw new RuggedException(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, info); } // set up the starting point of the fixed point method @@ -815,10 +814,20 @@ public class Rugged { // Check if the pixel is inside the sensor (with a margin) OR if the inverse location was impossible (null result) if (!pixelIsInside(sensorPixelGrid[uIndex][vIndex], sensor)) { + // In order for the dump to end nicely DumpManager.endNicely(); - // Impossible to find the point in the given min line - throw new RuggedException(RuggedMessages.INVALID_RANGE_FOR_LINES, minLine, maxLine, ""); + + if (sensorPixelGrid[uIndex][vIndex] == null) { + // Impossible to find the sensor pixel in the given range lines + final String info = "in given range lines (with atmospheric refraction) between lines" + minLine + " and " + maxLine; + throw new RuggedException(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, info); + } else { + // Impossible to find the sensor pixel + final double invLocationMargin = atmosphericRefraction.getComputationParameters().getInverseLocMargin(); + final String info = ": pixel = " + sensorPixelGrid[uIndex][vIndex].getPixelNumber() + " outside interval [ " + (-invLocationMargin) + " , " + (invLocationMargin + sensor.getNbPixels() - 1) + " [ (with atmospheric refraction margin = " + invLocationMargin + ")"; + throw new RuggedException(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, info); + } } } else { // groundGrid[uIndex][vIndex] == null: impossible to compute inverse loc because ground point not defined @@ -842,7 +851,10 @@ public class Rugged { * @return true if the pixel is inside the sensor */ private boolean pixelIsInside(final SensorPixel pixel, final LineSensor sensor) { - return pixel != null && pixel.getPixelNumber() >= -INVLOC_MARGIN && pixel.getPixelNumber() < INVLOC_MARGIN + sensor.getNbPixels() - 1; + // Get the inverse location margin + final double invLocationMargin = atmosphericRefraction.getComputationParameters().getInverseLocMargin(); + + return pixel != null && pixel.getPixelNumber() >= -invLocationMargin && pixel.getPixelNumber() < invLocationMargin + sensor.getNbPixels() - 1; } /** Computation, for the sensor pixels grid, of the direct location WITH atmospheric refraction. diff --git a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java index 966539c0..190decac 100644 --- a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java +++ b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java @@ -84,7 +84,8 @@ public enum RuggedMessages implements Localizable { UNSUPPORTED_REFINING_CONTEXT("refining using {0} rugged instance is not handled"), NO_LAYER_DATA("no atmospheric layer data at altitude {0} (lowest altitude: {1})"), INVALID_STEP("step {0} is not valid : {1}"), - INVALID_RANGE_FOR_LINES("range between min line {0} and max line {1} is invalid {2}"); + INVALID_RANGE_FOR_LINES("range between min line {0} and max line {1} is invalid {2}"), + SENSOR_PIXEL_NOT_FOUND("impossible to find sensor pixel {0}"); // CHECKSTYLE: resume JavadocVariable check diff --git a/src/main/java/org/orekit/rugged/refraction/AtmosphericComputationParameters.java b/src/main/java/org/orekit/rugged/refraction/AtmosphericComputationParameters.java index c92837eb..3f63b0f2 100644 --- a/src/main/java/org/orekit/rugged/refraction/AtmosphericComputationParameters.java +++ b/src/main/java/org/orekit/rugged/refraction/AtmosphericComputationParameters.java @@ -27,6 +27,7 @@ import org.orekit.rugged.utils.GridCreation; * @author Guylaine Prat * @since 2.1 */ + public class AtmosphericComputationParameters { /** Margin for definition of the interpolation grid. @@ -42,6 +43,16 @@ public class AtmosphericComputationParameters { private int pixelStep; /** Actual values for line step in case default are overwritten. */ private int lineStep; + + /** Default margin for computation of inverse location with atmospheric refraction correction. + * @since 3.0 + */ + private static final double DEFAULT_INVLOC_MARGIN = 0.8; + + /** Actual values for inverse location margin with atmospheric refraction in case default are overwritten. + * @since 3.0 + */ + private double invlocMargin; // Definition of grids for sensor (u = along pixel; v = along line) /** Linear grid in pixel. */ @@ -67,6 +78,7 @@ public class AtmosphericComputationParameters { public AtmosphericComputationParameters() { this.pixelStep = DEFAULT_STEP_PIXEL; this.lineStep = DEFAULT_STEP_LINE; + this.invlocMargin = DEFAULT_INVLOC_MARGIN; } /** Configuration of the interpolation grid. This grid is associated to the given sensor, @@ -119,7 +131,35 @@ public class AtmosphericComputationParameters { this.pixelStep = gridPixelStep; this.lineStep = gridLineStep; } + + /** + * Set the margin for computation of inverse location with atmospheric refraction correction. + * Overwrite the default value DEFAULT_INVLOC_MARGIN. + * No check is done about this margin. A recommended value is around 1. + * @param inverseLocMargin margin in pixel size to compute inverse location with atmospheric refraction correction. + * @since 3.0 + */ + public void setInverseLocMargin(final double inverseLocMargin) { + + this.invlocMargin = inverseLocMargin; + } + /** + * @return the inverse location margin for computation of inverse location with atmospheric refraction correction. + * @since 3.0 + */ + public double getInverseLocMargin () { + return this.invlocMargin; + } + + /** + * @return the default inverse location margin for computation of inverse location with atmospheric refraction correction. + * @since 3.0 + */ + public double getDefaultInverseLocMargin () { + return DEFAULT_INVLOC_MARGIN; + } + /** * @return the size of pixel grid */ diff --git a/src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java b/src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java index 5d2431bd..8e5639a3 100644 --- a/src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java +++ b/src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java @@ -142,6 +142,17 @@ public abstract class AtmosphericRefraction { public void setGridSteps(final int pixelStep, final int lineStep) { atmosphericParams.setGridSteps(pixelStep, lineStep); } + + /** + * Set the margin for computation of inverse location with atmospheric refraction correction. + * Overwrite the default value DEFAULT_INVLOC_MARGIN. + * No check is done about this margin. A recommended value is around 1. + * @param inverseLocMargin margin in pixel size to compute inverse location with atmospheric refraction correction. + * @since 3.0 + */ + public void setInverseLocMargin(final double inverseLocMargin) { + atmosphericParams.setInverseLocMargin(inverseLocMargin); + } /** Compute the correction functions for pixel and lines. * The corrections are computed for pixels and lines, on a regular grid at sensor level. @@ -174,9 +185,10 @@ public abstract class AtmosphericRefraction { gridDiffLine[pixelIndex][lineIndex] = diffLine; } else { - // Impossible to find the point in the given min line and max line - throw new RuggedException(RuggedMessages.INVALID_RANGE_FOR_LINES, - atmosphericParams.getMinLineSensor(), atmosphericParams.getMaxLineSensor(), ""); + // Impossible to find the sensor pixel in the given range lines + final String info = "in given range lines (with atmospheric refraction) between lines" + + atmosphericParams.getMinLineSensor() + " and " + atmosphericParams.getMaxLineSensor(); + throw new RuggedException(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, info); } } } diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_da.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_da.utf8 index 30a675f1..a7c75c85 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_da.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_da.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = skridt {0} er ikke gyldigt : {1} # range between min line {0} and max line {1} too small {2} INVALID_RANGE_FOR_LINES = interval mellem minimumslinje {0} og maksimumslinje {1} for lille {2} + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <MISSING TRANSLATION> 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 63f06fe2..a8b2fb56 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = <MISSING TRANSLATION> # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = <MISSING TRANSLATION> + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <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 ec839421..9e0acd4f 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = step {0} is not valid : {1} # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = range between min line {0} and max line {1} is invalid {2} + +# Impossible to find sensor pixel {0} +SENSOR_PIXEL_NOT_FOUND = impossible to find sensor pixel {0} 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 872c2fcb..96a452f2 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 @@ -96,3 +96,7 @@ INVALID_STEP = <MISSING TRANSLATION> # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = <MISSING TRANSLATION> + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <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 59152480..410304d0 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = le pas {0} n''est pas valable : {1} # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = l''écart entre la ligne min {0} et la ligne max {1} est non valide {2} + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = impossible de trouver le pixel senseur {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 7953c301..891edfa8 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = <MISSING TRANSLATION> # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = <MISSING TRANSLATION> + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <MISSING TRANSLATION> \ No newline at end of file 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 b6101683..19ee2263 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = Step {0} non valido: {1} # range between min line {0} and max line {1} too small {2} INVALID_RANGE_FOR_LINES = Scarto fra la linea min {0} e la linea max {1} troppo piccolo {2} + + # Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <MISSING TRANSLATION> \ No newline at end of file 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 33a5f7d5..70220984 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = steget {0} er ikke gyldig: {1} # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = avstanden mellom min linje {0} og max linje {1} er ugyldig {2} + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <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 d2a28660..ce0190cd 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 @@ -96,3 +96,6 @@ INVALID_STEP = <MISSING TRANSLATION> # range between min line {0} and max line {1} is invalid {2} INVALID_RANGE_FOR_LINES = <MISSING TRANSLATION> + +# Impossible to find sensor pixel in given range lines (with atmospheric refraction) between lines {0} and {1} +SENSOR_PIXEL_NOT_FOUND = <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 cfb7c1d0..5c19b72c 100644 --- a/src/test/java/org/orekit/rugged/api/RuggedTest.java +++ b/src/test/java/org/orekit/rugged/api/RuggedTest.java @@ -68,6 +68,7 @@ import org.orekit.rugged.adjustment.util.InitInterRefiningTest; import org.orekit.rugged.errors.RuggedException; import org.orekit.rugged.errors.RuggedMessages; import org.orekit.rugged.intersection.IgnoreDEMAlgorithm; +import org.orekit.rugged.intersection.IntersectionAlgorithm; import org.orekit.rugged.linesensor.LineDatation; import org.orekit.rugged.linesensor.LineSensor; import org.orekit.rugged.linesensor.LinearLineDatation; @@ -78,7 +79,9 @@ import org.orekit.rugged.los.TimeDependentLOS; import org.orekit.rugged.raster.RandomLandscapeUpdater; import org.orekit.rugged.raster.TileUpdater; import org.orekit.rugged.raster.VolcanicConeElevationUpdater; +import org.orekit.rugged.refraction.AtmosphericRefraction; import org.orekit.rugged.utils.DerivativeGenerator; +import org.orekit.rugged.utils.NormalizedGeodeticPoint; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScale; import org.orekit.time.TimeScalesFactory; @@ -880,6 +883,17 @@ public class RuggedTest { LinearLineDatation lineDatation = new LinearLineDatation(absDate, 0.03125d, 19.95565693384045); LineSensor lineSensor = new LineSensor("QUICK_LOOK", lineDatation, offset, new LOSBuilder(lineOfSight).build()); + + // in order not to have a problem when calling the pixelIsInside method (AtmosphericRefraction must be not null) + AtmosphericRefraction atmos = new AtmosphericRefraction() { + @Override + public NormalizedGeodeticPoint applyCorrection(Vector3D satPos, Vector3D satLos, + NormalizedGeodeticPoint rawIntersection, IntersectionAlgorithm algorithm) { + return rawIntersection; + } + }; + atmos.deactivateComputation(); + Rugged rugged = new RuggedBuilder(). setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID). setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF). @@ -889,6 +903,7 @@ public class RuggedTest { satellitePVList, 6, CartesianDerivativesFilter.USE_P, satelliteQList, 8, AngularDerivativesFilter.USE_R). addLineSensor(lineSensor). + setRefractionCorrection(atmos). build(); GeodeticPoint[] temp = rugged.directLocation("QUICK_LOOK", -250); diff --git a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java index 7f7d7afa..b3366efd 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 { private final String[] LANGUAGES_LIST = { "da", "de", "en", "es", "fr", "gl", "it", "no", "ro" } ; @Test public void testMessageNumber() { - Assert.assertEquals(33, RuggedMessages.values().length); + Assert.assertEquals(34, RuggedMessages.values().length); } @Test diff --git a/src/test/java/org/orekit/rugged/refraction/AtmosphericRefractionTest.java b/src/test/java/org/orekit/rugged/refraction/AtmosphericRefractionTest.java index 9a0dd896..fbda896d 100644 --- a/src/test/java/org/orekit/rugged/refraction/AtmosphericRefractionTest.java +++ b/src/test/java/org/orekit/rugged/refraction/AtmosphericRefractionTest.java @@ -8,7 +8,12 @@ import static org.junit.Assert.fail; import java.io.File; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; +import org.hipparchus.analysis.differentiation.Derivative; +import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Rotation; import org.hipparchus.geometry.euclidean.threed.RotationConvention; import org.hipparchus.geometry.euclidean.threed.Vector3D; @@ -19,6 +24,9 @@ import org.orekit.bodies.BodyShape; import org.orekit.bodies.GeodeticPoint; import org.orekit.data.DataContext; import org.orekit.data.DirectoryCrawler; +import org.orekit.frames.Frame; +import org.orekit.frames.FramesFactory; +import org.orekit.models.earth.ReferenceEllipsoid; import org.orekit.orbits.Orbit; import org.orekit.rugged.TestUtils; import org.orekit.rugged.api.AlgorithmId; @@ -37,12 +45,17 @@ import org.orekit.rugged.los.LOSBuilder; import org.orekit.rugged.los.TimeDependentLOS; import org.orekit.rugged.raster.RandomLandscapeUpdater; import org.orekit.rugged.raster.TileUpdater; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.rugged.utils.GeodeticUtilities; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.AngularDerivativesFilter; import org.orekit.utils.CartesianDerivativesFilter; import org.orekit.utils.Constants; +import org.orekit.utils.IERSConventions; +import org.orekit.utils.ParameterDriver; +import org.orekit.utils.TimeStampedAngularCoordinates; +import org.orekit.utils.TimeStampedPVCoordinates; public class AtmosphericRefractionTest { @@ -122,7 +135,7 @@ public class AtmosphericRefractionTest { ruggedWith.inverseLocation(sensorName, dummyGP, minLine, maxLine); Assert.fail("an exeption should have been thrown"); } catch (RuggedException re) { - Assert.assertEquals(RuggedMessages.INVALID_RANGE_FOR_LINES, re.getSpecifier()); + Assert.assertEquals(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, re.getSpecifier()); } try { @@ -131,7 +144,7 @@ public class AtmosphericRefractionTest { 210, maxLine); Assert.fail("an exeption should have been thrown"); } catch (RuggedException re) { - Assert.assertEquals(RuggedMessages.INVALID_RANGE_FOR_LINES, re.getSpecifier()); + Assert.assertEquals(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, re.getSpecifier()); } try { @@ -140,7 +153,7 @@ public class AtmosphericRefractionTest { minLine, 190); Assert.fail("an exeption should have been thrown"); } catch (RuggedException re) { - Assert.assertEquals(RuggedMessages.INVALID_RANGE_FOR_LINES, re.getSpecifier()); + Assert.assertEquals(RuggedMessages.SENSOR_PIXEL_NOT_FOUND, re.getSpecifier()); } } @@ -193,6 +206,101 @@ public class AtmosphericRefractionTest { return builder; } + /** + * Test for issue #391 + */ + @Test + public void testInverseLocationMargin() throws URISyntaxException { + + String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath(); + DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path))); + + RuggedBuilder builder = new RuggedBuilder(); + + Frame ecf = FramesFactory.getITRF(IERSConventions.IERS_2010, true); + builder.setEllipsoid(ReferenceEllipsoid.getWgs84(ecf)); + + MultiLayerModel atmosphere = new MultiLayerModel(builder.getEllipsoid()); + builder.setRefractionCorrection(atmosphere); + + builder.setLightTimeCorrection(true); + builder.setAberrationOfLightCorrection(true); + builder.setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID); + + AbsoluteDate start = AbsoluteDate.ARBITRARY_EPOCH; + AbsoluteDate end = start.shiftedBy(10); + AbsoluteDate middle = start.shiftedBy(end.durationFrom(start) / 2); + builder.setTimeSpan(start, end, 1e-3, 1e-3); + + final double h = 500e3; + Vector3D p = new Vector3D(6378137 + h, 0, 0); + Vector3D v = Vector3D.ZERO; + List<TimeStampedPVCoordinates> pvs = Arrays.asList( + new TimeStampedPVCoordinates(start, p, v), + new TimeStampedPVCoordinates(end, p, v)); + + Rotation rotation = new Rotation(Vector3D.MINUS_I, Vector3D.MINUS_K, Vector3D.PLUS_K, Vector3D.PLUS_I); + TimeStampedAngularCoordinates attitude = + new TimeStampedAngularCoordinates( + middle, rotation, + Vector3D.PLUS_I.scalarMultiply(0.1), Vector3D.ZERO); + List<TimeStampedAngularCoordinates> attitudes = Arrays.asList( + attitude.shiftedBy(start.durationFrom(attitude.getDate())), + attitude, + attitude.shiftedBy(end.durationFrom(attitude.getDate()))); + + builder.setTrajectory(ecf, + pvs, 2, CartesianDerivativesFilter.USE_P, + attitudes, 2, AngularDerivativesFilter.USE_R); + + final double iFov = 1e-6; + TimeDependentLOS los = new TimeDependentLOS() { + @Override + public int getNbPixels() { + return 1000; + } + + @Override + public Vector3D getLOS(int index, AbsoluteDate date) { + // simplistic pinhole camera, assumes small angle + final double center = getNbPixels() / 2.0; + final double x = (index - center); + final double los = x * iFov; + return new Vector3D(los, 0, 1); + } + + @Override + public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives( + int index, + AbsoluteDate date, + DerivativeGenerator<T> generator) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + public Stream<ParameterDriver> getParametersDrivers() { + return Stream.empty(); + } + }; + + LineSensor sensor = new LineSensor("sensor", + new LinearLineDatation(middle, 0, 1000), + Vector3D.ZERO, + los); + builder.addLineSensor(sensor); + + Rugged rugged = builder.build(); + + GeodeticPoint point = rugged.directLocation(sensor.getName(), 1000)[500]; + try { + final int maxLine = 4999; // works with 4980, fails with 4999 + rugged.inverseLocation(sensor.getName(), point, 0, maxLine); + Assert.fail("An exception should have been thrown"); + + } catch (RuggedException re) { + Assert.assertEquals(RuggedMessages.SENSOR_PIXEL_NOT_FOUND,re.getSpecifier()); + } + } @Test public void testBadConfig() { diff --git a/src/tutorials/java/fr/cs/examples/AtmosphericRefractionExamples.java b/src/tutorials/java/fr/cs/examples/AtmosphericRefractionExamples.java index a6e97066..b4a625b3 100644 --- a/src/tutorials/java/fr/cs/examples/AtmosphericRefractionExamples.java +++ b/src/tutorials/java/fr/cs/examples/AtmosphericRefractionExamples.java @@ -150,10 +150,17 @@ public class AtmosphericRefractionExamples { int pixelStep = 100; int lineStep = 100; atmosphericRefraction.setGridSteps(pixelStep, lineStep); + + // To compute the inverse location grid with atmospheric refraction, a default margin is available: + // atmosphericRefraction.getComputationParameters().getDefaultInverseLocMargin(); + + // but can be modified with: + // atmosphericRefraction.setInverseLocMargin(margin); // Build Rugged with atmospheric refraction model builder.setRefractionCorrection(atmosphericRefraction); Rugged ruggedWith = builder.build(); + // Direct location on a line WITHOUT and WITH atmospheric correction // ----------------------------------------------------------------- -- GitLab