Skip to content
Snippets Groups Projects
Commit 147cf5c4 authored by sesteves's avatar sesteves
Browse files

multiple improvements.

parent a1c97403
No related branches found
No related tags found
No related merge requests found
...@@ -19,7 +19,7 @@ package org.orekit.rugged.atmosphericrefraction; ...@@ -19,7 +19,7 @@ package org.orekit.rugged.atmosphericrefraction;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.orekit.rugged.errors.RuggedException; import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.raster.Tile; import org.orekit.rugged.intersection.IntersectionAlgorithm;
import org.orekit.rugged.utils.NormalizedGeodeticPoint; import org.orekit.rugged.utils.NormalizedGeodeticPoint;
/** /**
...@@ -28,6 +28,8 @@ import org.orekit.rugged.utils.NormalizedGeodeticPoint; ...@@ -28,6 +28,8 @@ import org.orekit.rugged.utils.NormalizedGeodeticPoint;
*/ */
public interface AtmosphericRefraction { public interface AtmosphericRefraction {
NormalizedGeodeticPoint getPointOnGround(Vector3D pos, Vector3D los, Vector3D zenith, double altitude, Tile tile) throws RuggedException; NormalizedGeodeticPoint applyCorrection(Vector3D satPos, Vector3D satLos, NormalizedGeodeticPoint rawIntersection,
IntersectionAlgorithm algorithm)
throws RuggedException;
} }
...@@ -33,8 +33,10 @@ import org.orekit.rugged.utils.NormalizedGeodeticPoint; ...@@ -33,8 +33,10 @@ import org.orekit.rugged.utils.NormalizedGeodeticPoint;
import org.orekit.utils.Constants; import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions; import org.orekit.utils.IERSConventions;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
...@@ -44,86 +46,113 @@ import java.util.TreeMap; ...@@ -44,86 +46,113 @@ import java.util.TreeMap;
*/ */
public class MultiLayerModel implements AtmosphericRefraction { public class MultiLayerModel implements AtmosphericRefraction {
// maps altitude (lower bound) to refraction index /** Observed body ellipsoid. */
private static Map<Double, Double> meanAtmosphericRefractions; private final ExtendedEllipsoid ellipsoid;
private static Map<Double, ExtendedEllipsoid> atmosphericEllipsoids; /** Constant refraction layers */
private final List<ConstantRefractionLayer> refractionLayers;
public MultiLayerModel() throws OrekitException {
meanAtmosphericRefractions = new TreeMap(Collections.reverseOrder()); public MultiLayerModel(final ExtendedEllipsoid ellipsoid)
meanAtmosphericRefractions.put(-1000.00000000000, 1.00030600000); throws OrekitException {
meanAtmosphericRefractions.put(0.00000000000, 1.00027800000); this.ellipsoid = ellipsoid;
meanAtmosphericRefractions.put(1000.00000000000, 1.00025200000);
meanAtmosphericRefractions.put(3000.00000000000, 1.00020600000); refractionLayers = new ArrayList<ConstantRefractionLayer>(15);
meanAtmosphericRefractions.put(5000.00000000000, 1.00016700000); refractionLayers.add(new ConstantRefractionLayer(100000.00, 1.000000));
meanAtmosphericRefractions.put(7000.00000000000, 1.00013400000); refractionLayers.add(new ConstantRefractionLayer( 50000.00, 1.000000));
meanAtmosphericRefractions.put(9000.00000000000, 1.00010600000); refractionLayers.add(new ConstantRefractionLayer( 40000.00, 1.000001));
meanAtmosphericRefractions.put(11000.00000000000, 1.00008300000); refractionLayers.add(new ConstantRefractionLayer( 30000.00, 1.000004));
meanAtmosphericRefractions.put(14000.00000000000, 1.00005200000); refractionLayers.add(new ConstantRefractionLayer( 23000.00, 1.000012));
meanAtmosphericRefractions.put(18000.00000000000, 1.00002800000); refractionLayers.add(new ConstantRefractionLayer( 18000.00, 1.000028));
meanAtmosphericRefractions.put(23000.00000000000, 1.00001200000); refractionLayers.add(new ConstantRefractionLayer( 14000.00, 1.000052));
meanAtmosphericRefractions.put(30000.00000000000, 1.00000400000); refractionLayers.add(new ConstantRefractionLayer( 11000.00, 1.000083));
meanAtmosphericRefractions.put(40000.00000000000, 1.00000100000); refractionLayers.add(new ConstantRefractionLayer( 9000.00, 1.000106));
meanAtmosphericRefractions.put(50000.00000000000, 1.00000000000); refractionLayers.add(new ConstantRefractionLayer( 7000.00, 1.000134));
meanAtmosphericRefractions.put(100000.00000000000, 1.00000000000); refractionLayers.add(new ConstantRefractionLayer( 5000.00, 1.000167));
refractionLayers.add(new ConstantRefractionLayer( 3000.00, 1.000206));
atmosphericEllipsoids = new HashMap<Double, ExtendedEllipsoid>(); refractionLayers.add(new ConstantRefractionLayer( 1000.00, 1.000252));
for (Double altitude : meanAtmosphericRefractions.keySet()) { refractionLayers.add(new ConstantRefractionLayer( 0.00, 1.000278));
OneAxisEllipsoid ellipsoid = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS + altitude, refractionLayers.add(new ConstantRefractionLayer( -1000.00, 1.000306));
Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true)); }
ellipsoid = new ExtendedEllipsoid(ellipsoid.getEquatorialRadius(), ellipsoid.getFlattening(),
ellipsoid.getBodyFrame()); public MultiLayerModel(final ExtendedEllipsoid ellipsoid, final List<ConstantRefractionLayer> refractionLayers)
atmosphericEllipsoids.put(altitude, (ExtendedEllipsoid) ellipsoid); throws OrekitException {
} this.ellipsoid = ellipsoid;
// TODO guarantee that list is already ordered by altitude?
this.refractionLayers = refractionLayers;
} }
@Override @Override
public NormalizedGeodeticPoint getPointOnGround(Vector3D initialPos, Vector3D initialLos, Vector3D initialZenith, public NormalizedGeodeticPoint applyCorrection(final Vector3D satPos, final Vector3D satLos,
double altitude, Tile tile) throws RuggedException { final NormalizedGeodeticPoint rawIntersection,
final IntersectionAlgorithm algorithm)
Vector3D pos = initialPos; throws RuggedException {
Vector3D los = initialLos;
Vector3D zenith = initialZenith;
double theta1 = Vector3D.angle(los, zenith), theta2;
double previousRefractionIndex = -1;
NormalizedGeodeticPoint gp = null;
for (Map.Entry<Double, Double> entry : meanAtmosphericRefractions.entrySet()) {
if (pos.getZ() < entry.getKey()) {
continue;
}
if (previousRefractionIndex > 0) { try {
theta2 = FastMath.asin(previousRefractionIndex * FastMath.sin(theta1) / entry.getValue());
// get new los Vector3D pos = satPos;
double a = FastMath.sqrt((1 - FastMath.pow(FastMath.cos(theta2), 2)) / Vector3D los = satLos;
(1 - FastMath.pow(FastMath.cos(theta1), 2))); Vector3D zenith = null;
double b = a * FastMath.cos(theta1) - FastMath.cos(theta2); double previousRefractionIndex = -1;
los = new Vector3D(a, los, b, zenith); GeodeticPoint gp = ellipsoid.transform(satPos, ellipsoid.getBodyFrame(), null);
theta1 = theta2; for(ConstantRefractionLayer refractionLayer : refractionLayers) {
}
if(refractionLayer.getLowestAltitude() > gp.getAltitude()) {
continue;
}
if (previousRefractionIndex > 0) {
// get new los
final double theta1 = Vector3D.angle(los, zenith);
final double theta2 = FastMath.asin(previousRefractionIndex * FastMath.sin(theta1) /
refractionLayer.getRefractionIndex());
final double cosTheta1 = FastMath.cos(theta1);
final double cosTheta2 = FastMath.cos(theta2);
if (altitude > entry.getKey()) { final double a = FastMath.sqrt((1 - cosTheta2 * cosTheta2) / (1 - cosTheta1 * cosTheta1));
break; final double b = a * cosTheta1 - cosTheta2;
los = new Vector3D(a, los, b, zenith);
}
if (rawIntersection.getAltitude() > refractionLayer.getLowestAltitude()) {
break;
}
// get intersection point
pos = ellipsoid.pointAtAltitude(pos, los, refractionLayer.getLowestAltitude());
gp = ellipsoid.transform(pos, ellipsoid.getBodyFrame(), null);
zenith = gp.getZenith();
previousRefractionIndex = refractionLayer.getRefractionIndex();
} }
// get intersection point final NormalizedGeodeticPoint newGeodeticPoint =
ExtendedEllipsoid ellipsoid = atmosphericEllipsoids.get(entry.getKey()); algorithm.refineIntersection(ellipsoid, pos, los, rawIntersection);
gp = ellipsoid.pointOnGround(pos, los, 0.0);
gp = new NormalizedGeodeticPoint(gp.getLatitude(), gp.getLongitude(), entry.getKey(), 0.0);
pos = ellipsoid.transform(gp); return newGeodeticPoint;
zenith = gp.getZenith();
previousRefractionIndex = entry.getValue(); } catch (OrekitException oe) {
throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
} }
}
}
class ConstantRefractionLayer {
private double lowestAltitude;
private double refractionIndex;
public ConstantRefractionLayer(double lowestAltitude, double refractionIndex) {
this.lowestAltitude = lowestAltitude;
this.refractionIndex = refractionIndex;
}
// gp = new NormalizedGeodeticPoint(gp.getLatitude(), gp.getLongitude(), 16, 0.0); public double getLowestAltitude() {
NormalizedGeodeticPoint newGeodeticPoint = tile.cellIntersection(gp, los, return lowestAltitude;
tile.getFloorLatitudeIndex(gp.getLatitude()), tile.getFloorLongitudeIndex(gp.getLongitude())); }
return newGeodeticPoint; public double getRefractionIndex() {
return refractionIndex;
} }
} }
...@@ -30,40 +30,29 @@ import org.orekit.rugged.intersection.duvenhage.MinMaxTreeTileFactory; ...@@ -30,40 +30,29 @@ import org.orekit.rugged.intersection.duvenhage.MinMaxTreeTileFactory;
import org.orekit.rugged.raster.Tile; import org.orekit.rugged.raster.Tile;
import org.orekit.rugged.raster.TileUpdater; import org.orekit.rugged.raster.TileUpdater;
import org.orekit.rugged.raster.TilesCache; import org.orekit.rugged.raster.TilesCache;
import org.orekit.rugged.utils.NormalizedGeodeticPoint;
public class MultiLayerModelTest extends AbstractAlgorithmTest { public class MultiLayerModelTest extends AbstractAlgorithmTest {
@Test @Test
public void testGetPointOnGround() throws OrekitException, RuggedException { public void testApplyCorrection() throws OrekitException, RuggedException {
setUpMayonVolcanoContext(); setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8); final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098); Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098);
Vector3D los = new Vector3D( 0.5127552821932051, -0.8254313129088879, -0.2361041470463311); Vector3D los = new Vector3D( 0.5127552821932051, -0.8254313129088879, -0.2361041470463311);
GeodeticPoint intersection = algorithm.refineIntersection(earth, position, los, NormalizedGeodeticPoint rawIntersection = algorithm.refineIntersection(earth, position, los,
algorithm.intersection(earth, position, los)); algorithm.intersection(earth, position, los));
Assert.assertNotNull(intersection); MultiLayerModel model = new MultiLayerModel(earth);
GeodeticPoint correctedIntersection = model.applyCorrection(position, los, rawIntersection, algorithm);
// intersection {lat: 13.4045888388 deg, lon: 123.0160362249 deg, alt: 16} double distance = Vector3D.distance(earth.transform(rawIntersection), earth.transform(correctedIntersection));
System.out.println("DISTANCE: " + distance);
// MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile(); // with the current code, this check fails, the distance is about 800m instead of a couple meters
// updater.updateTile(intersection.getLatitude(), intersection.getLongitude(), tile); Assert.assertEquals(0.0, distance, 2.0);
// tile.interpolateElevation(intersection.getLatitude(), intersection.getLongitude());
TilesCache cache = new TilesCache<MinMaxTreeTile>(new MinMaxTreeTileFactory(), updater, 8);
// locate the entry tile along the line-of-sight
Tile tile = cache.getTile(intersection.getLatitude(), intersection.getLongitude());
MultiLayerModel model = new MultiLayerModel();
GeodeticPoint gp = model.getPointOnGround(position, los, intersection.getZenith(), intersection.getAltitude(),
tile);
Assert.assertNotNull(gp);
} }
@Override @Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment