diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index d86e69c01afaefefa9dfc3ec6ce5aff28ab5b5bf..0a283fc59a0107a848ba3ea2d2595842ae79fdae 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 966539c0f71431477a3c9ff63d7b08008772c5ac..190decacec01e2d07a98a3ab69a3eb75f946d65f 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 c92837eb9d6231fd8140e84de73a2475380b0250..3f63b0f24b5c50450c365ddec2ac6a035ba429f5 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 5d2431bd4c0cae58b89eb94a45e9cca785d9622b..8e5639a3af2560762eebc1582490dfda7bf96130 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 30a675f16e0c3bb415f7866d69203832895380ef..a7c75c8597199af7458b4bb4f898510e8c2bd1ec 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 63f06fe26e823245d490aeab49e6a28714125ced..a8b2fb56e78e5118c8c5f33ee9a95f0e2b9a5cda 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 ec8394218db8d9c69365b155fed52d251c16a6aa..9e0acd4ffd30af87013f9e4233c6baf4f76f05ff 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 872c2fcb92de319989c71fcee05431ba5ffa6b91..96a452f206228aa3210b9ebe6f69ed1f4b1a4ec2 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 59152480f0f0a248198f43aa31e0b356e0affa4b..410304d0e49f9f32241a143c27c9536018e5088b 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 7953c301262bff78a6be8e08af1cb01cd78e29a5..891edfa8d62efbb4fbe6c8fc1afc8ea4381ecf57 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 b6101683412513d15e9a761c7e5ec9f25efa0595..19ee2263e5fe2f02f2d35916859533f25f4ae2f3 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 33a5f7d52284c566c277b958edbbb5a0d025777d..702209844c4d208674b04bfd4463201d9056afc8 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 d2a286608423c53dfbce9fc037c9dda42f8aacc9..ce0190cd0be141044bb877b66a6139f303bf1ce3 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 cfb7c1d0c52d48ccabbbff4eca5e0a151c5d9999..5c19b72cd724aed75241b1ce7eef7d8d1631b1b3 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 7f7d7afa4ddcd0399ebae2cbedbbe979b6a44aa5..b3366efd9377caab90d691071b74210c886ad7f3 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 9a0dd896aed15ef97fd80ab21407a5b011abc370..fbda896deca0711d5a7aa8298769b64b4f48e4f6 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 a6e9706695d505088c0778d4ea204b6833f604ab..b4a625b3c8306af631e5d07b8170febf6c177558 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 // -----------------------------------------------------------------