From f4c3d7702a76625a86ed5366dc968455b2ce188c Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Tue, 20 Sep 2016 14:50:53 +0200 Subject: [PATCH] Improved tests. --- atmospheric-deviation.csv | 41 ---- atmospheric-deviation.gp | 13 - atmospheric-deviation.pdf | Bin 8812 -> 0 bytes .../refraction/MultiLayerModelTest.java | 230 ++++++++++++++---- 4 files changed, 177 insertions(+), 107 deletions(-) delete mode 100644 atmospheric-deviation.csv delete mode 100644 atmospheric-deviation.gp delete mode 100644 atmospheric-deviation.pdf diff --git a/atmospheric-deviation.csv b/atmospheric-deviation.csv deleted file mode 100644 index 2807245d..00000000 --- a/atmospheric-deviation.csv +++ /dev/null @@ -1,41 +0,0 @@ -angle,correction -0.0,0 -0.01,0 -0.02,0 -0.03,0 -0.04,0 -0.05,0 -0.060000000000000005,0 -0.07,0 -0.08,0 -0.09,0 -0.09999999999999999,0 -0.10999999999999999,0 -0.11999999999999998,0 -0.12999999999999998,0 -0.13999999999999999,0 -0.15,0 -0.16,1 -0.17,1 -0.18000000000000002,1 -0.19000000000000003,1 -0.20000000000000004,1 -0.21000000000000005,1 -0.22000000000000006,1 -0.23000000000000007,1 -0.24000000000000007,1 -0.25000000000000006,1 -0.26000000000000006,1 -0.2700000000000001,1 -0.2800000000000001,1 -0.2900000000000001,1 -0.3000000000000001,1 -0.3100000000000001,1 -0.3200000000000001,1 -0.3300000000000001,1 -0.34000000000000014,1 -0.35000000000000014,1 -0.36000000000000015,1 -0.37000000000000016,1 -0.38000000000000017,2 -0.3900000000000002,2 diff --git a/atmospheric-deviation.gp b/atmospheric-deviation.gp deleted file mode 100644 index 88716c6e..00000000 --- a/atmospheric-deviation.gp +++ /dev/null @@ -1,13 +0,0 @@ -# gnuplot script file for plotting bandwidth over time -#!/usr/bin/gnuplot - - -set terminal pdf size 3,2 -set output 'atmospheric-deviation.pdf' -set grid - -set title "Atmospheric Correction" -set xlabel "angle (radians)" -set ylabel "correction (meters)" - -plot "atmospheric-deviation.csv" using 1:0 with lines title "" diff --git a/atmospheric-deviation.pdf b/atmospheric-deviation.pdf deleted file mode 100644 index 1ce2e9bf36894482b4061c28bf544f2d59192897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8812 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 diff --git a/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java b/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java index 409a6a71..27c595f6 100644 --- a/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java +++ b/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java @@ -16,46 +16,63 @@ */ package org.orekit.rugged.refraction; +import org.hipparchus.analysis.UnivariateFunction; import org.hipparchus.geometry.euclidean.threed.Rotation; import org.hipparchus.geometry.euclidean.threed.RotationConvention; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; import org.junit.Assert; import org.junit.Test; -import org.orekit.bodies.GeodeticPoint; import org.orekit.errors.OrekitException; import org.orekit.rugged.errors.RuggedException; +import org.orekit.rugged.errors.RuggedMessages; import org.orekit.rugged.intersection.AbstractAlgorithmTest; import org.orekit.rugged.intersection.IntersectionAlgorithm; import org.orekit.rugged.intersection.duvenhage.DuvenhageAlgorithm; import org.orekit.rugged.raster.TileUpdater; import org.orekit.rugged.utils.NormalizedGeodeticPoint; -import java.io.FileNotFoundException; -import java.io.PrintWriter; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class MultiLayerModelTest extends AbstractAlgorithmTest { @Test - public void testApplyCorrection() throws OrekitException, RuggedException, FileNotFoundException { + public void testAlmostNadir() throws OrekitException, RuggedException { setUpMayonVolcanoContext(); final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); final Vector3D los = new Vector3D( 0.5127552821932051, -0.8254313129088879, -0.2361041470463311); - final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los, - algorithm.intersection(earth, position, los)); + final NormalizedGeodeticPoint rawIntersection = + algorithm.refineIntersection(earth, position, los, + algorithm.intersection(earth, position, los)); MultiLayerModel model = new MultiLayerModel(earth); - GeodeticPoint correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); + NormalizedGeodeticPoint correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); double distance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection)); // this is almost a Nadir observation (LOS deviates between 1.4 and 1.6 degrees from vertical) // so the refraction correction is small Assert.assertEquals(0.0553797, distance, 1.0e-6); + } + + @Test + public void testNoOpRefraction() throws OrekitException, RuggedException { + + setUpMayonVolcanoContext(); + final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); + final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); + final Vector3D los = los(position, FastMath.toRadians(50.0)); + final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los, + algorithm.intersection(earth, position, los)); + + MultiLayerModel model = new MultiLayerModel(earth); + NormalizedGeodeticPoint correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); + double distance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection)); // a test with indices all set to 1.0 - correction must be zero final int numberOfLayers = 16; @@ -66,78 +83,185 @@ public class MultiLayerModelTest extends AbstractAlgorithmTest { model = new MultiLayerModel(earth, refractionLayers); correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); distance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection)); - Assert.assertEquals(0.0, distance, 0.001); + Assert.assertEquals(0.0, distance, 1.0e-9); + } + + @Test + public void testReversedAtmosphere() + throws OrekitException, RuggedException, IllegalArgumentException, + IllegalAccessException, NoSuchFieldException, SecurityException { + + setUpMayonVolcanoContext(); + final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); + final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); + final Vector3D los = los(position, FastMath.toRadians(50.0)); + final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los, + algorithm.intersection(earth, position, los)); + + MultiLayerModel baseModel = new MultiLayerModel(earth); + NormalizedGeodeticPoint correctedIntersection = baseModel.applyCorrection(position, los, rawIntersection, algorithm); // an intentionally flawed atmosphere with refractive indices decreasing with altitude, // that should exhibit a LOS bending upwards - refractionLayers = new ArrayList<ConstantRefractionLayer>(numberOfLayers); - for(int i = numberOfLayers - 1; i >= 0; i--) { - refractionLayers.add(new ConstantRefractionLayer(i * 1.0e4, 1.0 + i*i*1e-6)); + Field refractionLayersField = MultiLayerModel.class.getDeclaredField("refractionLayers"); + refractionLayersField.setAccessible(true); + @SuppressWarnings("unchecked") + List<ConstantRefractionLayer> baseRefractionLayers = + (List<ConstantRefractionLayer>) refractionLayersField.get(baseModel); + List<ConstantRefractionLayer> denserRefractionLayers = new ArrayList<>(); + for (final ConstantRefractionLayer layer : baseRefractionLayers) { + denserRefractionLayers.add(new ConstantRefractionLayer(layer.getLowestAltitude(), + 1.0 / layer.getRefractiveIndex())); } - model = new MultiLayerModel(earth, refractionLayers); - correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); - double anglePosRawIntersection = Vector3D.angle(position, earth.transform(rawIntersection)); + MultiLayerModel reversedModel = new MultiLayerModel(earth, denserRefractionLayers); + NormalizedGeodeticPoint reversedIntersection = reversedModel.applyCorrection(position, los, rawIntersection, algorithm); + double anglePosRawIntersection = Vector3D.angle(position, earth.transform(rawIntersection)); double anglePosCorrectedIntersection = Vector3D.angle(position, earth.transform(correctedIntersection)); - Assert.assertTrue(anglePosRawIntersection < anglePosCorrectedIntersection); + double anglePosReversedIntersection = Vector3D.angle(position, earth.transform(reversedIntersection)); + + // with regular atmosphere, the ray bends downwards, + // so the ground point is closer to the sub-satellite point than the raw intersection + Assert.assertTrue(anglePosCorrectedIntersection < anglePosRawIntersection); + + // with reversed atmosphere, the ray bends upwards, + // so the ground point is farther from the sub-satellite point than the raw intersection + Assert.assertTrue(anglePosReversedIntersection > anglePosRawIntersection); + // the points are almost aligned (for distances around 20m, Earth curvature is small enough) + double dRawCorrected = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection)); + double dRawReversed = Vector3D.distance(earth.transform(rawIntersection), earth.transform(reversedIntersection)); + double dReversedCorrected = Vector3D.distance(earth.transform(reversedIntersection), earth.transform(correctedIntersection)); + Assert.assertEquals(dRawCorrected + dRawReversed, dReversedCorrected, 1.0e-12 * dReversedCorrected); + + } + + @Test + public void testTwoAtmospheres() + throws OrekitException, RuggedException, IllegalArgumentException, + IllegalAccessException, NoSuchFieldException, SecurityException { + + setUpMayonVolcanoContext(); + final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); + final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); + final Vector3D los = los(position, FastMath.toRadians(50.0)); + final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los, + algorithm.intersection(earth, position, los)); // a comparison between two atmospheres, one more dense than the other and showing correction // is more important with high indices - List<ConstantRefractionLayer> baseRefracLayers = new ArrayList<ConstantRefractionLayer>(numberOfLayers); - List<ConstantRefractionLayer> denserRefracLayers = new ArrayList<ConstantRefractionLayer>(numberOfLayers); - for(int i = numberOfLayers - 1; i >= 0; i--) { - double baseRefractiveIndex = FastMath.pow(numberOfLayers - i + 1, 2) * 1e-6; - baseRefracLayers.add(new ConstantRefractionLayer(i * 1.0e4, baseRefractiveIndex)); - denserRefracLayers.add(new ConstantRefractionLayer(i * 1.0e4, baseRefractiveIndex + 1e-3)); + MultiLayerModel baseModel = new MultiLayerModel(earth); + Field refractionLayersField = MultiLayerModel.class.getDeclaredField("refractionLayers"); + refractionLayersField.setAccessible(true); + @SuppressWarnings("unchecked") + List<ConstantRefractionLayer> baseRefractionLayers = + (List<ConstantRefractionLayer>) refractionLayersField.get(baseModel); + List<ConstantRefractionLayer> denserRefractionLayers = new ArrayList<>(); + double previousBaseN = 1.0; + double previousDenserN = 1.0; + double factor = 1.00001; + for (final ConstantRefractionLayer layer : baseRefractionLayers) { + final double currentBaseN = layer.getRefractiveIndex(); + final double baseRatio = currentBaseN / previousBaseN; + final double currentDenserN = previousDenserN * factor * baseRatio; + denserRefractionLayers.add(new ConstantRefractionLayer(layer.getLowestAltitude(), + currentDenserN)); + previousBaseN = currentBaseN; + previousDenserN = currentDenserN; } - MultiLayerModel baseModel = new MultiLayerModel(earth, baseRefracLayers); - MultiLayerModel denserModel = new MultiLayerModel(earth, denserRefracLayers); - GeodeticPoint baseIntersection = baseModel.applyCorrection(position, los, rawIntersection, algorithm); - GeodeticPoint denserIntersection = denserModel.applyCorrection(position, los, rawIntersection, algorithm); - double baseDistance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(baseIntersection)); + MultiLayerModel denserModel = new MultiLayerModel(earth, denserRefractionLayers); + NormalizedGeodeticPoint baseIntersection = baseModel.applyCorrection(position, los, rawIntersection, algorithm); + NormalizedGeodeticPoint denserIntersection = denserModel.applyCorrection(position, los, rawIntersection, algorithm); + double baseDistance = Vector3D.distance(earth.transform(rawIntersection), + earth.transform(baseIntersection)); double denserDistance = Vector3D.distance(earth.transform(rawIntersection), - earth.transform(denserIntersection)); - // denserDistance: 291.6042252928431, baseDistance: 2710.1036961651967 - // Assert.assertTrue(denserDistance > baseDistance); + earth.transform(denserIntersection)); + Assert.assertTrue(denserDistance > baseDistance); + } - // a test with a single refraction layer - refractionLayers = new ArrayList<ConstantRefractionLayer>(numberOfLayers); - refractionLayers.add(new ConstantRefractionLayer(0, 1.2)); - model = new MultiLayerModel(earth, refractionLayers); - correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); - distance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection)); - Assert.assertEquals(0.0, distance, 0.0); + @Test + public void testMissingLayers() throws OrekitException, RuggedException { + setUpMayonVolcanoContext(); + final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); + final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); + final Vector3D los = los(position, FastMath.toRadians(50.0)); + final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los, + algorithm.intersection(earth, position, los)); + final double h = rawIntersection.getAltitude(); - // deviation should increase as the angle between los and zenith increases - PrintWriter writer = new PrintWriter("atmospheric-deviation.csv"); - writer.println("angle,correction"); + MultiLayerModel model = new MultiLayerModel(earth, + Collections.singletonList(new ConstantRefractionLayer(h + 100.0, + 1.5))); + try { + model.applyCorrection(position, los, rawIntersection, algorithm); + Assert.fail("an exception should have been thrown"); + } catch (RuggedException re) { + Assert.assertEquals(RuggedMessages.NO_LAYER_DATA, re.getSpecifier()); + Assert.assertEquals(h, ((Double) re.getParts()[0]).doubleValue(), 1.0e-6); + Assert.assertEquals(h + 100.0, ((Double) re.getParts()[1]).doubleValue(), 1.0e-6); + } - GeodeticPoint satGP = earth.transform(position, earth.getBodyFrame(), null); - Vector3D nadir = satGP.getNadir(); - Vector3D horizontal = nadir.orthogonal(); - for (double alpha = 0; alpha < 0.4; alpha += 0.01) { - Vector3D rotatingLos = new Rotation(horizontal, alpha, RotationConvention.VECTOR_OPERATOR).applyTo(nadir); - NormalizedGeodeticPoint uncorrectedIntersection = algorithm.refineIntersection(earth, position, rotatingLos, - algorithm.intersection(earth, position, rotatingLos)); + } - model = new MultiLayerModel(earth); - correctedIntersection = model.applyCorrection(position, rotatingLos, uncorrectedIntersection, algorithm); - distance = Vector3D.distance(earth.transform(uncorrectedIntersection), - earth.transform(correctedIntersection)); + @Test + public void testLayersBelowDEM() throws OrekitException, RuggedException { - writer.println(alpha + "," + FastMath.round(distance)); - } - writer.close(); + setUpMayonVolcanoContext(); + final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); + final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); + final Vector3D los = los(position, FastMath.toRadians(50.0)); + final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los, + algorithm.intersection(earth, position, los)); + MultiLayerModel model = new MultiLayerModel(earth, + Collections.singletonList(new ConstantRefractionLayer(rawIntersection.getAltitude() - 100.0, + 1.5))); + NormalizedGeodeticPoint correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm); + double distance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection)); + Assert.assertEquals(0.0, distance, 1.0e-20); + } + + @Test + public void testDivingAngleChange() throws OrekitException, RuggedException { + + setUpMayonVolcanoContext(); + final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); + final Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); + AtmosphericRefraction model = new MultiLayerModel(earth); + + // deviation should increase from 0 to about 17m + // as the angle between los and nadir increases from 0 to 50 degrees + // the reference model below has been obtained by fitting the test results themselves + // it is NOT considered a full featured model, it's just a helper function for this specific test + UnivariateFunction reference = alpha -> 1.17936 * FastMath.tan((2.94613 - 1.40162 * alpha) * alpha); + + for (double alpha = 0; alpha < FastMath.toRadians(50.0); alpha += 0.1) { + final Vector3D rotatingLos = los(position, alpha); + final NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, rotatingLos, + algorithm.intersection(earth, position, rotatingLos)); + + final NormalizedGeodeticPoint correctedIntersection = model.applyCorrection(position, rotatingLos, rawIntersection, algorithm); + final double distance = Vector3D.distance(earth.transform(rawIntersection), + earth.transform(correctedIntersection)); + Assert.assertEquals(reference.value(alpha), distance, 0.12); + } } + private Vector3D los(final Vector3D position, final double angleFromNadir) + throws OrekitException { + final Vector3D nadir = earth.transform(position, earth.getBodyFrame(), null).getNadir(); + final Rotation losRotation = new Rotation(nadir.orthogonal(), angleFromNadir, + RotationConvention.VECTOR_OPERATOR); + return losRotation.applyTo(nadir); + } + @Override protected IntersectionAlgorithm createAlgorithm(TileUpdater updater, int maxCachedTiles) { return new DuvenhageAlgorithm(updater, maxCachedTiles, false); } + } -- GitLab