From 43bb8fd83a383affadb55c631c85943f183040f7 Mon Sep 17 00:00:00 2001
From: Luc Maisonobe <luc@orekit.org>
Date: Wed, 2 Apr 2014 11:21:44 +0200
Subject: [PATCH] Improved accuracy by taking speed of light into account in
 transforms.

---
 .../org/orekit/rugged/core/RuggedImpl.java    | 20 ++++++++---
 .../rugged/core/SpacecraftToObservedBody.java | 34 +++++++++++--------
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/src/main/java/org/orekit/rugged/core/RuggedImpl.java b/src/main/java/org/orekit/rugged/core/RuggedImpl.java
index 7f52151d..c0625db0 100644
--- a/src/main/java/org/orekit/rugged/core/RuggedImpl.java
+++ b/src/main/java/org/orekit/rugged/core/RuggedImpl.java
@@ -374,17 +374,27 @@ public class RuggedImpl implements Rugged {
             // select the sensor
             final Sensor sensor = getSensor(sensorName);
 
-            // compute once the transform between spacecraft and observed body
-            final AbsoluteDate date = sensor.getDate(lineNumber);
-            final Transform t = scToBody.getTransform(date);
+            // compute the approximate transform between spacecraft and observed body
+            final AbsoluteDate date        = sensor.getDate(lineNumber);
+            final Transform    scToInert   = scToBody.getScToInertial(date);
+            final Transform    inertToBody = scToBody.getInertialToBody(date);
+            final Transform    approximate = new Transform(date, scToInert, inertToBody);
 
             // compute localization of each pixel
             final GroundPoint[] gp = new GroundPoint[sensor.getNbPixels()];
             for (int i = 0; i < gp.length; ++i) {
+
+                // fix light travel time
+                final Vector3D  sP     = approximate.transformPosition(sensor.getPosition(i));
+                final Vector3D  sL     = approximate.transformVector(sensor.getLos(i));
+                final Vector3D  eP     = ellipsoid.transform(ellipsoid.pointOnGround(sP, sL));
+                final double    deltaT = eP.distance(sP) / Constants.SPEED_OF_LIGHT;
+                final Transform fixed  = new Transform(date, scToInert, inertToBody.shiftedBy(-deltaT));
+
                 final GeodeticPoint geodetic =
                         algorithm.intersection(ellipsoid,
-                                               t.transformPosition(sensor.getPosition(i)),
-                                               t.transformVector(sensor.getLos(i)));
+                                               fixed.transformPosition(sensor.getPosition(i)),
+                                               fixed.transformVector(sensor.getLos(i)));
                 gp[i] = new GroundPoint(geodetic.getLatitude(),
                                         geodetic.getLongitude(),
                                         geodetic.getAltitude());
diff --git a/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java b/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java
index 5ec98eec..044471c8 100644
--- a/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java
+++ b/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java
@@ -21,18 +21,14 @@ import org.orekit.attitudes.AttitudeProvider;
 import org.orekit.errors.OrekitException;
 import org.orekit.frames.Frame;
 import org.orekit.frames.Transform;
-import org.orekit.frames.TransformProvider;
 import org.orekit.time.AbsoluteDate;
 import org.orekit.utils.PVCoordinates;
 import org.orekit.utils.PVCoordinatesProvider;
 
-/** Transform provider from Spacecraft frame to observed body frame.
+/** Provider for observation transforms.
  * @author Luc Maisonobe
  */
-class SpacecraftToObservedBody implements TransformProvider {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20140311L;
+class SpacecraftToObservedBody {
 
     /** Inertial frame. */
     private Frame inertialFrame;
@@ -61,9 +57,12 @@ class SpacecraftToObservedBody implements TransformProvider {
         this.aProvider     = aProvider;
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public Transform getTransform(final AbsoluteDate date)
+    /** Get transform from spacecraft to inertial frame.
+     * @param date date of the transform
+     * @return transform from spacecraft to inertial frame
+     * @exception OrekitException if spacecraft position or attitude cannot be computed at date
+     */
+    public Transform getScToInertial(final AbsoluteDate date)
         throws OrekitException {
 
         // propagate/interpolate orbit and attitude
@@ -71,15 +70,22 @@ class SpacecraftToObservedBody implements TransformProvider {
         final Attitude attitude   = aProvider.getAttitude(pvProvider, date, inertialFrame);
 
         // compute transform from spacecraft frame to inertial frame
-        final Transform scToInert = new Transform(date,
+        return new Transform(date,
                                                   new Transform(date, attitude.getOrientation().revert()),
                                                   new Transform(date, pv));
 
-        // compute transform from inertial frame to body frame
-        final Transform inertToBody = inertialFrame.getTransformTo(bodyFrame, date);
+    }
 
-        // combine transforms
-        return new Transform(date, scToInert, inertToBody);
+    /** Get transform from inertial frame to body frame.
+     * @param date date of the transform
+     * @return transform from inertial frame to body frame
+     * @exception OrekitException if frames cannot be computed at date
+     */
+    public Transform getInertialToBody(final AbsoluteDate date)
+        throws OrekitException {
+
+        // compute transform from inertial frame to body frame
+        return inertialFrame.getTransformTo(bodyFrame, date);
 
     }
 
-- 
GitLab