diff --git a/core/src/main/java/org/orekit/rugged/api/FixedLOS.java b/core/src/main/java/org/orekit/rugged/api/FixedLOS.java new file mode 100644 index 0000000000000000000000000000000000000000..5c24f8d0e43bb26a2b7eac70755b2d3f1516e91c --- /dev/null +++ b/core/src/main/java/org/orekit/rugged/api/FixedLOS.java @@ -0,0 +1,43 @@ +/* Copyright 2013-2014 CS Systèmes d'Information + * Licensed to CS Systèmes d'Information (CS) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * CS licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.orekit.rugged.api; + +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.time.AbsoluteDate; + +/** Line-of-sight which does not depends on time. + * @see LineSensor + * @author Luc Maisonobe + */ +public class FixedLOS implements TimeDependentLOS { + + /** Fixed direction for los. */ + final Vector3D los; + + /** Simple constructor. + * @param los fixed direction for the line of sight + */ + public FixedLOS(final Vector3D los) { + this.los = los; + } + + /** {@inheritDoc}} */ + public Vector3D getLOS(AbsoluteDate date) { + return los; + } + +} diff --git a/core/src/main/java/org/orekit/rugged/api/LineSensor.java b/core/src/main/java/org/orekit/rugged/api/LineSensor.java index f0bfd9a8cb919a6d7117a330ae4e90b95a658e99..6971fa4fe288568bd4b3c66d22d9045818218d04 100644 --- a/core/src/main/java/org/orekit/rugged/api/LineSensor.java +++ b/core/src/main/java/org/orekit/rugged/api/LineSensor.java @@ -39,7 +39,7 @@ public class LineSensor { private final Vector3D position; /** Pixels lines-of-sight. */ - private final Vector3D[] x; + private final List<TimeDependentLOS> los; /** Simple constructor. * @param name name of the sensor @@ -48,17 +48,12 @@ public class LineSensor { * @param datationModel datation model */ public LineSensor(final String name, final LineDatation datationModel, - final Vector3D position, final List<Vector3D> los) { + final Vector3D position, final List<TimeDependentLOS> los) { this.name = name; this.datationModel = datationModel; this.position = position; - - // normalize lines-of-sight - this.x = new Vector3D[los.size()]; - for (int i = 0; i < los.size(); ++i) { - x[i] = los.get(i).normalize(); - } + this.los = los; } @@ -73,15 +68,16 @@ public class LineSensor { * @return number of pixels */ public int getNbPixels() { - return x.length; + return los.size(); } - /** Get the pixel normalized line-of-sight. + /** Get the pixel normalized line-of-sight at some date. + * @param date current date * @param i pixel index (must be between 0 and {@link #getNbPixels()} * @return pixel normalized line-of-sight */ - public Vector3D getLos(final int i) { - return x[i]; + public Vector3D getLos(final AbsoluteDate date, final int i) { + return los.get(i).getLOS(date).normalize(); } /** Get the date. diff --git a/core/src/main/java/org/orekit/rugged/api/Rugged.java b/core/src/main/java/org/orekit/rugged/api/Rugged.java index d37d8bd482e7db93b2b3a7f0e99eb9ba22caee3c..e7bdde20bdcadd6b5b5557348c23fdc88fb169fa 100644 --- a/core/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/core/src/main/java/org/orekit/rugged/api/Rugged.java @@ -742,7 +742,7 @@ public class Rugged { final GeodeticPoint[] gp = new GeodeticPoint[sensor.getNbPixels()]; for (int i = 0; i < sensor.getNbPixels(); ++i) { - final Vector3D obsLInert = scToInert.transformVector(sensor.getLos(i)); + final Vector3D obsLInert = scToInert.transformVector(sensor.getLos(date, i)); final Vector3D lInert; if (aberrationOfLightCorrection) { // apply aberration of light correction @@ -765,7 +765,7 @@ public class Rugged { if (lightTimeCorrection) { // compute DEM intersection with light time correction final Vector3D sP = approximate.transformPosition(sensor.getPosition()); - final Vector3D sL = approximate.transformVector(sensor.getLos(i)); + final Vector3D sL = approximate.transformVector(sensor.getLos(date, i)); final Vector3D eP1 = ellipsoid.transform(ellipsoid.pointOnGround(sP, sL, 0.0)); final double deltaT1 = eP1.distance(sP) / Constants.SPEED_OF_LIGHT; final Transform shifted1 = inertToBody.shiftedBy(-deltaT1); @@ -1005,7 +1005,7 @@ public class Rugged { new SensorPixelCrossing(sensor, planeCrossing.getMeanPlaneNormal(), crossingResult.getTargetDirection().toVector3D(), MAX_EVAL, COARSE_INVERSE_LOCALIZATION_ACCURACY); - final double coarsePixel = pixelCrossing.locatePixel(); + final double coarsePixel = pixelCrossing.locatePixel(crossingResult.getDate()); if (Double.isNaN(coarsePixel)) { // target is out of search interval return null; @@ -1014,10 +1014,9 @@ public class Rugged { // fix line by considering the closest pixel exact position and line-of-sight // (this pixel might point towards a direction slightly above or below the mean sensor plane) final int lowIndex = FastMath.max(0, FastMath.min(sensor.getNbPixels() - 2, (int) FastMath.floor(coarsePixel))); - final Vector3D lowLOS = sensor.getLos(lowIndex); - final Vector3D highLOS = sensor.getLos(lowIndex + 1); + final Vector3D lowLOS = sensor.getLos(crossingResult.getDate(), lowIndex); + final Vector3D highLOS = sensor.getLos(crossingResult.getDate(), lowIndex + 1); final Vector3D localZ = Vector3D.crossProduct(lowLOS, highLOS); - final Vector3D localY = Vector3D.crossProduct(localZ, lowLOS); final DerivativeStructure beta = FieldVector3D.angle(crossingResult.getTargetDirection(), localZ); final double deltaL = (0.5 * FastMath.PI - beta.getValue()) / beta.getPartialDerivative(1); final double fixedLine = crossingResult.getLine() + deltaL; @@ -1025,11 +1024,17 @@ public class Rugged { crossingResult.getTargetDirection().getY().taylor(deltaL), crossingResult.getTargetDirection().getZ().taylor(deltaL)).normalize(); + // fix neighbouring pixels + final AbsoluteDate fixedDate = sensor.getDate(fixedLine); + final Vector3D fixedX = sensor.getLos(fixedDate, lowIndex); + final Vector3D fixedZ = Vector3D.crossProduct(fixedX, sensor.getLos(fixedDate, lowIndex + 1)); + final Vector3D fixedY = Vector3D.crossProduct(fixedZ, fixedX); + // fix pixel - final double pixelWidth = FastMath.atan2(Vector3D.dotProduct(highLOS, localY), - Vector3D.dotProduct(highLOS, lowLOS)); - final double alpha = FastMath.atan2(Vector3D.dotProduct(fixedDirection, localY), - Vector3D.dotProduct(fixedDirection, lowLOS)); + final double pixelWidth = FastMath.atan2(Vector3D.dotProduct(highLOS, fixedY), + Vector3D.dotProduct(highLOS, fixedX)); + final double alpha = FastMath.atan2(Vector3D.dotProduct(fixedDirection, fixedY), + Vector3D.dotProduct(fixedDirection, fixedX)); final double fixedPixel = lowIndex + alpha / pixelWidth; return new SensorPixel(fixedLine, fixedPixel); diff --git a/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java b/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java index 21a92acddcfaa885911a78d6261a208cba6c812e..a23434968881cea9d535c2e3d7215dc2f074be5a 100644 --- a/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java +++ b/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java @@ -101,16 +101,17 @@ class SensorMeanPlaneCrossing { this.accuracy = accuracy; this.scToBody = scToBody; - this.midLine = 0.5 * (minLine + maxLine); - final AbsoluteDate midDate = sensor.getDate(midLine); - this.midBodyToInert = scToBody.getBodyToInertial(midDate); - this.midScToInert = scToBody.getScToInertial(midDate); + this.midLine = 0.5 * (minLine + maxLine); + final AbsoluteDate midDate = sensor.getDate(midLine); + this.midBodyToInert = scToBody.getBodyToInertial(midDate); + this.midScToInert = scToBody.getScToInertial(midDate); - this.meanPlaneNormal = computeMeanPlaneNormal(); + this.meanPlaneNormal = computeMeanPlaneNormal(midDate); } /** Compute the plane containing origin that best fits viewing directions point cloud. + * @param midDate middle date * <p> * The normal is oriented such traversing pixels in increasing indices * order corresponds is consistent with trigonometric order (i.e. @@ -118,14 +119,14 @@ class SensorMeanPlaneCrossing { * </p> * @return normal of the mean plane */ - private Vector3D computeMeanPlaneNormal() { + private Vector3D computeMeanPlaneNormal(final AbsoluteDate midDate) { // build a centered data matrix // (for each viewing direction, we add both the direction and its // opposite, thus ensuring the plane will contain origin) final RealMatrix matrix = MatrixUtils.createRealMatrix(3, 2 * sensor.getNbPixels()); for (int i = 0; i < sensor.getNbPixels(); ++i) { - final Vector3D l = sensor.getLos(i); + final Vector3D l = sensor.getLos(midDate, i); matrix.setEntry(0, 2 * i, l.getX()); matrix.setEntry(1, 2 * i, l.getY()); matrix.setEntry(2, 2 * i, l.getZ()); @@ -143,8 +144,8 @@ class SensorMeanPlaneCrossing { final Vector3D singularVector = new Vector3D(svd.getU().getColumn(2)).normalize(); // check rotation order - final Vector3D first = sensor.getLos(0); - final Vector3D last = sensor.getLos(sensor.getNbPixels() - 1); + final Vector3D first = sensor.getLos(midDate, 0); + final Vector3D last = sensor.getLos(midDate, sensor.getNbPixels() - 1); if (Vector3D.dotProduct(singularVector, Vector3D.crossProduct(first, last)) >= 0) { return singularVector; } else { @@ -182,6 +183,9 @@ class SensorMeanPlaneCrossing { /** Container for mean plane crossing result. */ public static class CrossingResult { + /** Crossing date. */ + private final AbsoluteDate crossingDate; + /** Crossing line. */ private final double crossingLine; @@ -189,15 +193,24 @@ class SensorMeanPlaneCrossing { private final FieldVector3D<DerivativeStructure> targetDirection; /** Simple constructor. + * @param crossingDate crossing date * @param crossingLine crossing line * @param targetDirection target direction in spacecraft frame */ - private CrossingResult(final double crossingLine, + private CrossingResult(final AbsoluteDate crossingDate, final double crossingLine, final FieldVector3D<DerivativeStructure> targetDirection) { + this.crossingDate = crossingDate; this.crossingLine = crossingLine; this.targetDirection = targetDirection; } + /** Get the crossing date. + * @return crossing date + */ + public AbsoluteDate getDate() { + return crossingDate; + } + /** Get the crossing line. * @return crossing line */ @@ -246,7 +259,7 @@ class SensorMeanPlaneCrossing { final double deltaL = (0.5 * FastMath.PI - beta.getValue()) / beta.getPartialDerivative(1); if (FastMath.abs(deltaL) <= accuracy) { // return immediately, without doing any additional evaluation! - return new CrossingResult(crossingLine, targetDirection); + return new CrossingResult(sensor.getDate(crossingLine), crossingLine, targetDirection); } crossingLine += deltaL; diff --git a/core/src/main/java/org/orekit/rugged/api/SensorPixelCrossing.java b/core/src/main/java/org/orekit/rugged/api/SensorPixelCrossing.java index 6cd31e53edb56dc3e90b3bba6b0b7cda3eedd76e..157cbb1c1f67a786cd4443976c9198c5305a964f 100644 --- a/core/src/main/java/org/orekit/rugged/api/SensorPixelCrossing.java +++ b/core/src/main/java/org/orekit/rugged/api/SensorPixelCrossing.java @@ -24,6 +24,7 @@ import org.apache.commons.math3.exception.TooManyEvaluationsException; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.util.FastMath; import org.orekit.errors.OrekitExceptionWrapper; +import org.orekit.time.AbsoluteDate; /** Class devoted to locate where ground point crosses a sensor line. * <p> @@ -65,11 +66,12 @@ class SensorPixelCrossing { } /** Locate pixel along sensor line. + * @param date current date * @return pixel location ({@code Double.NaN} if the first and last * pixels of the line do not bracket a location) * @exception RuggedException if the maximum number of evaluations is exceeded */ - public double locatePixel() throws RuggedException { + public double locatePixel(final AbsoluteDate date) throws RuggedException { try { // set up function evaluating to 0.0 where target matches pixel @@ -77,7 +79,7 @@ class SensorPixelCrossing { /** {@inheritDoc} */ @Override public double value(final double x) throws OrekitExceptionWrapper { - return Vector3D.angle(cross, getLOS(x)) - 0.5 * FastMath.PI; + return Vector3D.angle(cross, getLOS(date, x)) - 0.5 * FastMath.PI; } }; @@ -95,17 +97,19 @@ class SensorPixelCrossing { } /** Interpolate sensor pixels at some pixel index. + * @param date current date * @param x pixel index * @return interpolated direction for specified index */ - private Vector3D getLOS(final double x) { + private Vector3D getLOS(final AbsoluteDate date, final double x) { // find surrounding pixels final int iInf = FastMath.max(0, FastMath.min(sensor.getNbPixels() - 2, (int) FastMath.floor(x))); final int iSup = iInf + 1; // interpolate - return new Vector3D(iSup - x, sensor.getLos(iInf), x - iInf, sensor.getLos(iSup)).normalize(); + return new Vector3D(iSup - x, sensor.getLos(date, iInf), + x - iInf, sensor.getLos(date, iSup)).normalize(); } diff --git a/core/src/main/java/org/orekit/rugged/api/TimeDependentLOS.java b/core/src/main/java/org/orekit/rugged/api/TimeDependentLOS.java new file mode 100644 index 0000000000000000000000000000000000000000..d7f6014a141bba5a5d6c623e5275acaf2adb3e8a --- /dev/null +++ b/core/src/main/java/org/orekit/rugged/api/TimeDependentLOS.java @@ -0,0 +1,34 @@ +/* Copyright 2013-2014 CS Systèmes d'Information + * Licensed to CS Systèmes d'Information (CS) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * CS licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.orekit.rugged.api; + +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.time.AbsoluteDate; + +/** Interface representing a line-of-sight which depends on time. + * @see LineSensor + * @author Luc Maisonobe + */ +public interface TimeDependentLOS { + + /** Get the line of sight for a given date. + * @param date date + * @return line of sight + */ + Vector3D getLOS(AbsoluteDate date); + +} diff --git a/core/src/test/java/org/orekit/rugged/api/RuggedTest.java b/core/src/test/java/org/orekit/rugged/api/RuggedTest.java index fb2c2158fd271c3ba0e1e265fb276c01abae1ca1..b6a46d3a1287b66d6e29bbb81b4a5383312d7a92 100644 --- a/core/src/test/java/org/orekit/rugged/api/RuggedTest.java +++ b/core/src/test/java/org/orekit/rugged/api/RuggedTest.java @@ -303,8 +303,8 @@ public class RuggedTest { // position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass // los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, - FastMath.toRadians(10.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, + FastMath.toRadians(10.0), dimension); // linear datation model: at reference time we get line 1000, and the rate is one line every 1.5ms LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3); @@ -384,8 +384,8 @@ public class RuggedTest { // position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass // los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, - FastMath.toRadians(10.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, + FastMath.toRadians(10.0), dimension); // linear datation model: at reference time we get line 200, and the rate is one line every 1.5ms LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3); @@ -451,8 +451,8 @@ public class RuggedTest { // position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass // los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, - FastMath.toRadians(10.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I, + FastMath.toRadians(10.0), dimension); // linear datation model: at reference time we get line 200, and the rate is one line every 1.5ms LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3); @@ -506,9 +506,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -571,9 +570,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -599,7 +597,8 @@ public class RuggedTest { for (int i = 0; i < gpLine.length; ++i) { GeodeticPoint gpPixel = - rugged.directLocalization(lineSensor.getDate(100), lineSensor.getPosition(), lineSensor.getLos(i)); + rugged.directLocalization(lineSensor.getDate(100), lineSensor.getPosition(), + lineSensor.getLos(lineSensor.getDate(100), 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); @@ -624,9 +623,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -654,7 +652,8 @@ public class RuggedTest { for (int i = 0; i < gpLine.length; ++i) { GeodeticPoint gpPixel = - rugged.directLocalization(lineSensor.getDate(100), lineSensor.getPosition(), lineSensor.getLos(i)); + rugged.directLocalization(lineSensor.getDate(100), lineSensor.getPosition(), + lineSensor.getLos(lineSensor.getDate(100), 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); @@ -679,9 +678,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -741,9 +739,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -803,9 +800,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -850,9 +846,8 @@ public class RuggedTest { // 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 = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(1.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(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); @@ -1001,10 +996,9 @@ public class RuggedTest { // 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 roughly at 50° roll (sensor-dependent), 2.6" per pixel Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, - FastMath.toRadians(50.0 - 0.001 * i)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(dimension * 2.6 / 3600.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, + FastMath.toRadians(50.0 - 0.001 * i)).applyTo(Vector3D.PLUS_K), + Vector3D.PLUS_I, FastMath.toRadians(dimension * 2.6 / 3600.0), dimension); // linear datation model: at reference time we get roughly middle line, and the rate is one line every 1.5ms LineDatation lineDatation = new LinearLineDatation(crossing, i + dimension / 2, 1.0 / 1.5e-3); @@ -1146,35 +1140,35 @@ public class RuggedTest { satellitePVList, 8, CartesianDerivativesFilter.USE_PV, satelliteQList, 8, AngularDerivativesFilter.USE_R, 0.001); - List<Vector3D> lineOfSight = new ArrayList<Vector3D>(); - lineOfSight.add(new Vector3D(-0.011204, 0.181530, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181518, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181505, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181492, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181480, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181467, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181455, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181442, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181430, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181417, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181405, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.181392, 1d).normalize()); - - lineOfSight.add(new Vector3D(-0.011204, 0.149762, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149749, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149737, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149724, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149712, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149699, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149686, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149674, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149661, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149649, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149636, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149624, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149611, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149599, 1d).normalize()); - lineOfSight.add(new Vector3D(-0.011204, 0.149586, 1d).normalize()); + List<TimeDependentLOS> lineOfSight = new ArrayList<TimeDependentLOS>(); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181530, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181518, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181505, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181492, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181480, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181467, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181455, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181442, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181430, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181417, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181405, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.181392, 1d).normalize())); + + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149762, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149749, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149737, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149724, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149712, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149699, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149686, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149674, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149661, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149649, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149636, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149624, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149611, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149599, 1d).normalize())); + lineOfSight.add(new FixedLOS(new Vector3D(-0.011204, 0.149586, 1d).normalize())); AbsoluteDate absDate = new AbsoluteDate("2009-12-11T16:58:51.593", gps); LinearLineDatation lineDatation = new LinearLineDatation(absDate, 1d, 638.5696040868454); @@ -1298,10 +1292,10 @@ public class RuggedTest { satellitePVList.get(0).getDate(), satellitePVList.get(satellitePVList.size() - 1).getDate(), 10.0, satellitePVList, 6, CartesianDerivativesFilter.USE_P, satelliteQList, 8, AngularDerivativesFilter.USE_R, 0.1); - List<Vector3D> lineOfSight = new ArrayList<Vector3D>(); - lineOfSight.add(new Vector3D(0.0046536264d, -0.1851800945d, 1d).normalize()); - lineOfSight.add(new Vector3D(0.0000001251d, -0.0002815246d, 1d).normalize()); - lineOfSight.add(new Vector3D(0.0046694108d, 0.1853863933d, 1d).normalize()); + List<TimeDependentLOS> lineOfSight = new ArrayList<TimeDependentLOS>(); + lineOfSight.add(new FixedLOS(new Vector3D(0.0046536264d, -0.1851800945d, 1d))); + lineOfSight.add(new FixedLOS(new Vector3D(0.0000001251d, -0.0002815246d, 1d))); + lineOfSight.add(new FixedLOS(new Vector3D(0.0046694108d, 0.1853863933d, 1d))); AbsoluteDate absDate = new AbsoluteDate("2013-07-07T17:16:36.857", gps); LinearLineDatation lineDatation = new LinearLineDatation(absDate, 0.03125d, 19.95565693384045); @@ -1340,10 +1334,10 @@ public class RuggedTest { // 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 nadir, 2.6" per pixel, 3" sagitta Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSCurvedLine(Vector3D.PLUS_K, Vector3D.PLUS_I, - FastMath.toRadians(dimension * 2.6 / 3600.0), - FastMath.toRadians(3.0 / 3600.0), - dimension); + List<TimeDependentLOS> los = createLOSCurvedLine(Vector3D.PLUS_K, Vector3D.PLUS_I, + FastMath.toRadians(dimension * 2.6 / 3600.0), + FastMath.toRadians(3.0 / 3600.0), + dimension); // linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3); @@ -1414,9 +1408,9 @@ public class RuggedTest { // 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, 2.6" per pixel Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(dimension * 2.6 / 3600.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), + Vector3D.PLUS_I, + FastMath.toRadians(dimension * 2.6 / 3600.0), dimension); // linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3); @@ -1500,9 +1494,9 @@ public class RuggedTest { // 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, 2.6" per pixel Vector3D position = new Vector3D(1.5, 0, -0.2); - List<Vector3D> los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), - Vector3D.PLUS_I, - FastMath.toRadians(dimension * 2.6 / 3600.0), dimension); + List<TimeDependentLOS> los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K), + Vector3D.PLUS_I, + FastMath.toRadians(dimension * 2.6 / 3600.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); @@ -1624,24 +1618,24 @@ public class RuggedTest { } - private List<Vector3D> createLOSPerfectLine(Vector3D center, Vector3D normal, double halfAperture, int n) { - List<Vector3D> list = new ArrayList<Vector3D>(n); + private List<TimeDependentLOS> createLOSPerfectLine(Vector3D center, Vector3D normal, double halfAperture, int n) { + List<TimeDependentLOS> list = new ArrayList<TimeDependentLOS>(n); for (int i = 0; i < n; ++i) { double alpha = (halfAperture * (2 * i + 1 - n)) / (n - 1); - list.add(new Rotation(normal, alpha).applyTo(center)); + list.add(new FixedLOS(new Rotation(normal, alpha).applyTo(center))); } return list; } - private List<Vector3D> createLOSCurvedLine(Vector3D center, Vector3D normal, - double halfAperture, double sagitta, int n) { + private List<TimeDependentLOS> createLOSCurvedLine(Vector3D center, Vector3D normal, + double halfAperture, double sagitta, int n) { Vector3D u = Vector3D.crossProduct(center, normal); - List<Vector3D> list = new ArrayList<Vector3D>(n); + List<TimeDependentLOS> list = new ArrayList<TimeDependentLOS>(n); for (int i = 0; i < n; ++i) { double x = (2.0 * i + 1.0 - n) / (n - 1); double alpha = x * halfAperture; double beta = x * x * sagitta; - list.add(new Rotation(normal, alpha).applyTo(new Rotation(u, beta).applyTo(center))); + list.add(new FixedLOS(new Rotation(normal, alpha).applyTo(new Rotation(u, beta).applyTo(center)))); } return list; } diff --git a/core/src/test/java/org/orekit/rugged/api/SensorMeanPlaneCrossingTest.java b/core/src/test/java/org/orekit/rugged/api/SensorMeanPlaneCrossingTest.java index 4c799351ebfccda5e694cbe14ef5dc65afa33126..e8ddb1e47a11e4b591993b7fbc30596807995128 100644 --- a/core/src/test/java/org/orekit/rugged/api/SensorMeanPlaneCrossingTest.java +++ b/core/src/test/java/org/orekit/rugged/api/SensorMeanPlaneCrossingTest.java @@ -66,10 +66,10 @@ public class SensorMeanPlaneCrossingTest { final Vector3D cross = Vector3D.crossProduct(normal, fovCenter); // build lists of pixels regularly spread on a perfect plane - final List<Vector3D> los = new ArrayList<Vector3D>(); + final List<TimeDependentLOS> los = new ArrayList<TimeDependentLOS>(); for (int i = -1000; i <= 1000; ++i) { final double alpha = i * 0.17 / 1000; - los.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross)); + los.add(new FixedLOS(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross))); } final LineSensor sensor = new LineSensor("perfect line", @@ -96,7 +96,7 @@ public class SensorMeanPlaneCrossingTest { final Vector3D cross = Vector3D.crossProduct(normal, fovCenter); // build lists of pixels regularly spread on a perfect plane - final List<Vector3D> los = new ArrayList<Vector3D>(); + final List<TimeDependentLOS> los = new ArrayList<TimeDependentLOS>(); for (int i = -1000; i <= 1000; ++i) { final double alpha = i * 0.17 / 10 + 1.0e-5 * random.nextDouble(); final double delta = 1.0e-5 * random.nextDouble(); @@ -104,7 +104,7 @@ public class SensorMeanPlaneCrossingTest { final double sA = FastMath.sin(alpha); final double cD = FastMath.cos(delta); final double sD = FastMath.sin(delta); - los.add(new Vector3D(cA * cD, fovCenter, sA * cD, cross, sD, normal)); + los.add(new FixedLOS(new Vector3D(cA * cD, fovCenter, sA * cD, cross, sD, normal))); } final LineSensor sensor = new LineSensor("noisy line", diff --git a/design/direct-localization-class-diagram.puml b/design/direct-localization-class-diagram.puml index e4e73d4fb2e786a2907851f45fbf7f6f78daa04c..f49203d89438e3bc3e8dc3d79a94dd110c3f241d 100644 --- a/design/direct-localization-class-diagram.puml +++ b/design/direct-localization-class-diagram.puml @@ -61,7 +61,7 @@ class LineSensor IntersectionAlgorithm "1" <--o Rugged : delegate DEM intersection ExtendedEllipsoid <-- Rugged : convert geodetic points - Rugged --> LineSensor : getLOS(pixel) + Rugged --> LineSensor : getLOS(date, pixel) Rugged --> LineSensor : getDate(line) SpacecraftToObservedBody <-- Rugged : convert positions/directions } diff --git a/design/rugged-design.odt b/design/rugged-design.odt index 296c73fdaf4e1e7af50aaae2bcbb85dcd59ba407..4be3e90bf3bcb9d3582705071aa026c82f87e9d0 100644 Binary files a/design/rugged-design.odt and b/design/rugged-design.odt differ