Skip to content
Snippets Groups Projects
Commit 1f170e5f authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Added a dedicated function for single pixel direct localization.

parent 2767ddaa
No related branches found
No related tags found
No related merge requests found
......@@ -798,6 +798,80 @@ public class Rugged {
}
}
/** Direct localization of a single line-of-sight.
* @param date date of the localization
* @param pixel position in spacecraft frame
* @param los normalized line-of-sight in spacecraft frame
* @return ground position of all pixels of the specified sensor line
* @exception RuggedException if line cannot be localized, or sensor is unknown
*/
public GeodeticPoint directLocalization(final AbsoluteDate date, final Vector3D position, final Vector3D los)
throws RuggedException {
try {
// compute the approximate transform between spacecraft and observed body
final Transform scToInert = scToBody.getScToInertial(date);
final Transform inertToBody = scToBody.getInertialToBody(date);
final Transform approximate = new Transform(date, scToInert, inertToBody);
final Vector3D spacecraftVelocity =
scToInert.transformPVCoordinates(PVCoordinates.ZERO).getVelocity();
// compute localization of specified pixel
final Vector3D pInert = scToInert.transformPosition(position);
final Vector3D obsLInert = scToInert.transformVector(los);
final Vector3D lInert;
if (aberrationOfLightCorrection) {
// apply aberration of light correction
// as the spacecraft velocity is small with respect to speed of light,
// we use classical velocity addition and not relativistic velocity addition
// we look for a positive k such that: c * lInert + vsat = k * obsLInert
// with lInert normalized
final double a = obsLInert.getNormSq();
final double b = -Vector3D.dotProduct(obsLInert, spacecraftVelocity);
final double c = spacecraftVelocity.getNormSq() - Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT;
final double s = FastMath.sqrt(b * b - a * c);
final double k = (b > 0) ? -c / (s + b) : (s - b) / a;
lInert = new Vector3D( k / Constants.SPEED_OF_LIGHT, obsLInert,
-1.0 / Constants.SPEED_OF_LIGHT, spacecraftVelocity);
} else {
// don't apply aberration of light correction
lInert = obsLInert;
}
if (lightTimeCorrection) {
// compute DEM intersection with light time correction
final Vector3D sP = approximate.transformPosition(position);
final Vector3D sL = approximate.transformVector(los);
final Vector3D eP1 = ellipsoid.transform(ellipsoid.pointOnGround(sP, sL));
final double deltaT1 = eP1.distance(sP) / Constants.SPEED_OF_LIGHT;
final Transform shifted1 = inertToBody.shiftedBy(-deltaT1);
final GeodeticPoint gp1 = algorithm.intersection(ellipsoid,
shifted1.transformPosition(pInert),
shifted1.transformVector(lInert));
final Vector3D eP2 = ellipsoid.transform(gp1);
final double deltaT2 = eP2.distance(sP) / Constants.SPEED_OF_LIGHT;
final Transform shifted2 = inertToBody.shiftedBy(-deltaT2);
return algorithm.refineIntersection(ellipsoid,
shifted2.transformPosition(pInert),
shifted2.transformVector(lInert),
gp1);
} else {
// compute DEM intersection without light time correction
final Vector3D pBody = inertToBody.transformPosition(pInert);
final Vector3D lBody = inertToBody.transformVector(lInert);
return algorithm.refineIntersection(ellipsoid, pBody, lBody,
algorithm.intersection(ellipsoid, pBody, lBody));
}
} catch (OrekitException oe) {
throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
}
}
/** Find the date at which sensor sees a ground point.
* <p>
* This method is a partial {@link #inverseLocalization(String,
......
......@@ -554,6 +554,59 @@ public class RuggedTest {
}
@Test
public void testLocalizationsinglePoint()
throws RuggedException, OrekitException, URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = createEarth();
final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
List<Vector3D> los = createLOS(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I,
FastMath.toRadians(1.0), dimension);
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new Rugged(updater, 8, AlgorithmId.DUVENHAGE,
EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
minDate, maxDate, 5.0,
orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
CartesianDerivativesFilter.USE_PV,
orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2,
AngularDerivativesFilter.USE_R, 0.001);
rugged.addLineSensor(lineSensor);
GeodeticPoint[] gpLine = rugged.directLocalization("line", 100);
for (int i = 0; i < gpLine.length; ++i) {
GeodeticPoint gpPixel =
rugged.directLocalization(lineSensor.getDate(100), lineSensor.getPosition(), lineSensor.getLos(i));
Assert.assertEquals(gpLine[i].getLatitude(), gpPixel.getLatitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getLongitude(), gpPixel.getLongitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getAltitude(), gpPixel.getAltitude(), 1.0e-10);
}
}
@Test
public void testBasicScan()
throws RuggedException, OrekitException, URISyntaxException {
......
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