diff --git a/src/main/java/org/orekit/rugged/errors/Dump.java b/src/main/java/org/orekit/rugged/errors/Dump.java index af9ef5d50eb77f64b0fe2a661fb3952c3687a57a..ea538a7a1f52b6155e26f12957ea969726be77e9 100644 --- a/src/main/java/org/orekit/rugged/errors/Dump.java +++ b/src/main/java/org/orekit/rugged/errors/Dump.java @@ -16,11 +16,6 @@ */ package org.orekit.rugged.errors; -import org.hipparchus.geometry.euclidean.threed.Rotation; -import org.hipparchus.geometry.euclidean.threed.Vector3D; -import org.hipparchus.util.FastMath; -import org.hipparchus.util.OpenIntToDoubleHashMap; -import org.hipparchus.util.Pair; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Calendar; @@ -30,6 +25,11 @@ import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import org.hipparchus.geometry.euclidean.threed.Rotation; +import org.hipparchus.geometry.euclidean.threed.Vector3D; +import org.hipparchus.util.FastMath; +import org.hipparchus.util.OpenIntToDoubleHashMap; +import org.hipparchus.util.Pair; import org.orekit.bodies.GeodeticPoint; import org.orekit.errors.OrekitException; import org.orekit.frames.FactoryManagedFrame; @@ -39,7 +39,6 @@ import org.orekit.rugged.api.AlgorithmId; import org.orekit.rugged.linesensor.LineSensor; import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing; import org.orekit.rugged.linesensor.SensorPixel; -import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing.CrossingResult; import org.orekit.rugged.raster.Tile; import org.orekit.rugged.utils.ExtendedEllipsoid; import org.orekit.rugged.utils.SpacecraftToObservedBody; @@ -500,41 +499,43 @@ class Dump { * @exception RuggedException if frames cannot be computed at mid date */ public void setMeanPlane(final SensorMeanPlaneCrossing meanPlane) throws RuggedException { - if (this.meanPlane == null) { - this.meanPlane = meanPlane; - int nbResults = 0; - for (final CrossingResult result : meanPlane.getCachedResults()) { - if (result != null) { - ++nbResults; - } - } - writer.format(Locale.US, - "sensor mean plane: sensorName %s minLine %d maxLine %d maxEval %d accuracy %22.15e normal %22.15e %22.15e %22.15e cachedResults %d", - dumpName, - meanPlane.getMinLine(), meanPlane.getMaxLine(), - meanPlane.getMaxEval(), meanPlane.getAccuracy(), - meanPlane.getMeanPlaneNormal().getX(), meanPlane.getMeanPlaneNormal().getY(), meanPlane.getMeanPlaneNormal().getZ(), - nbResults); - for (int i = 0; i < nbResults; ++i) { - final CrossingResult result = meanPlane.getCachedResults()[i]; + try { + if (this.meanPlane == null) { + this.meanPlane = meanPlane; + final long nbResults = meanPlane.getCachedResults().count(); writer.format(Locale.US, - " lineNumber %22.15e date %s target %22.15e %22.15e %22.15e targetDirection %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e", - result.getLine(), convertDate(result.getDate()), - result.getTarget().getX(), result.getTarget().getY(), result.getTarget().getZ(), - result.getTargetDirection().getX().getValue(), - result.getTargetDirection().getY().getValue(), - result.getTargetDirection().getZ().getValue(), - result.getTargetDirection().getZ().getPartialDerivative(1), - result.getTargetDirection().getY().getPartialDerivative(1), - result.getTargetDirection().getZ().getPartialDerivative(1)); - } - writer.format(Locale.US, "%n"); - - // ensure the transforms for mid date are dumped - final AbsoluteDate midDate = meanPlane.getSensor().getDate(0.5 * (meanPlane.getMinLine() + meanPlane.getMaxLine())); - meanPlane.getScToBody().getBodyToInertial(midDate); - meanPlane.getScToBody().getScToInertial(midDate); + "sensor mean plane: sensorName %s minLine %d maxLine %d maxEval %d accuracy %22.15e normal %22.15e %22.15e %22.15e cachedResults %d", + dumpName, + meanPlane.getMinLine(), meanPlane.getMaxLine(), + meanPlane.getMaxEval(), meanPlane.getAccuracy(), + meanPlane.getMeanPlaneNormal().getX(), meanPlane.getMeanPlaneNormal().getY(), meanPlane.getMeanPlaneNormal().getZ(), + nbResults); + meanPlane.getCachedResults().forEach(result -> { + try { + writer.format(Locale.US, + " lineNumber %22.15e date %s target %22.15e %22.15e %22.15e targetDirection %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e", + result.getLine(), convertDate(result.getDate()), + result.getTarget().getX(), result.getTarget().getY(), result.getTarget().getZ(), + result.getTargetDirection().getX().getValue(), + result.getTargetDirection().getY().getValue(), + result.getTargetDirection().getZ().getValue(), + result.getTargetDirection().getZ().getPartialDerivative(1), + result.getTargetDirection().getY().getPartialDerivative(1), + result.getTargetDirection().getZ().getPartialDerivative(1)); + } catch (RuggedException re) { + throw new RuggedExceptionWrapper(re); + } + }); + writer.format(Locale.US, "%n"); + + // ensure the transforms for mid date are dumped + final AbsoluteDate midDate = meanPlane.getSensor().getDate(0.5 * (meanPlane.getMinLine() + meanPlane.getMaxLine())); + meanPlane.getScToBody().getBodyToInertial(midDate); + meanPlane.getScToBody().getScToInertial(midDate); + } + } catch (RuggedExceptionWrapper rew) { + throw rew.getException(); } } diff --git a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java index 95dfecb5e1dca6516f2769f2f714af5a712c8a27..738199459e8bb9fe1d82e9857c43070926eac083 100644 --- a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java +++ b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java @@ -35,6 +35,7 @@ import java.io.ObjectOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -372,7 +373,7 @@ public class DumpReplayer { parsedSensor.meanPlane.maxEval, parsedSensor.meanPlane.accuracy, parsedSensor.meanPlane.normal, - parsedSensor.meanPlane.cachedResults)); + Arrays.stream(parsedSensor.meanPlane.cachedResults))); } builder.addLineSensor(sensor); } diff --git a/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java b/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java index 5509bebe4edc949a87fc776cea9653bf01a5a0a3..3726f4429aceb941d8d936644e430cdcee06d773 100644 --- a/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java +++ b/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java @@ -16,6 +16,10 @@ */ package org.orekit.rugged.linesensor; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + import org.hipparchus.analysis.UnivariateFunction; import org.hipparchus.analysis.differentiation.DerivativeStructure; import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver; @@ -90,7 +94,7 @@ public class SensorMeanPlaneCrossing { private final double accuracy; /** Cached results. */ - private final CrossingResult[] cachedResults; + private final List<CrossingResult> cachedResults; /** Simple constructor. * @param sensor sensor to consider @@ -111,7 +115,8 @@ public class SensorMeanPlaneCrossing { final int maxEval, final double accuracy) throws RuggedException { this(sensor, scToBody, minLine, maxLine, lightTimeCorrection, aberrationOfLightCorrection, - maxEval, accuracy, computeMeanPlaneNormal(sensor, minLine, maxLine), new CrossingResult[0]); + maxEval, accuracy, computeMeanPlaneNormal(sensor, minLine, maxLine), + Stream.<CrossingResult>builder().build()); } /** Simple constructor. @@ -134,7 +139,7 @@ public class SensorMeanPlaneCrossing { final boolean aberrationOfLightCorrection, final int maxEval, final double accuracy, final Vector3D meanPlaneNormal, - final CrossingResult[] cachedResults) + final Stream<CrossingResult> cachedResults) throws RuggedException { this.sensor = sensor; @@ -153,8 +158,12 @@ public class SensorMeanPlaneCrossing { this.meanPlaneNormal = meanPlaneNormal; - this.cachedResults = new CrossingResult[CACHED_RESULTS]; - System.arraycopy(cachedResults, 0, this.cachedResults, 0, cachedResults.length); + this.cachedResults = new ArrayList<CrossingResult>(CACHED_RESULTS); + cachedResults.forEach(crossingResult -> { + if (crossingResult != null && this.cachedResults.size() < CACHED_RESULTS) { + this.cachedResults.add(crossingResult); + } + }); } @@ -261,11 +270,11 @@ public class SensorMeanPlaneCrossing { return meanPlaneNormal; } - /** Get the cached previous results. - * @return mean plane normal + /** Get cached previous results. + * @return cached previous results */ - public CrossingResult[] getCachedResults() { - return cachedResults; + public Stream<CrossingResult> getCachedResults() { + return cachedResults.stream(); } /** Container for mean plane crossing result. */ @@ -344,14 +353,10 @@ public class SensorMeanPlaneCrossing { Transform scToInert = midScToInert; // count the number of available results - int n = 0; - while (n < cachedResults.length && cachedResults[n] != null) { - ++n; - } - if (n >= 4) { + if (cachedResults.size() >= 4) { // we already have computed at lest 4 values, we attempt to build a linear // model to guess a better start line - final double guessedCrossingLine = guessStartLine(n, target); + final double guessedCrossingLine = guessStartLine(target); if (guessedCrossingLine >= minLine && guessedCrossingLine <= maxLine) { crossingLine = guessedCrossingLine; final AbsoluteDate date = sensor.getDate(crossingLine); @@ -399,11 +404,11 @@ public class SensorMeanPlaneCrossing { } if (FastMath.abs(deltaL) <= accuracy) { // return immediately, without doing any additional evaluation! - for (int k = cachedResults.length - 1; k > 0; --k) { - cachedResults[k] = cachedResults[k - 1]; + if (cachedResults.size() >= CACHED_RESULTS) { + cachedResults.remove(cachedResults.size() - 1); } - cachedResults[0] = new CrossingResult(sensor.getDate(crossingLine), crossingLine, target, targetDirection); - return cachedResults[0]; + cachedResults.add(0, new CrossingResult(sensor.getDate(crossingLine), crossingLine, target, targetDirection)); + return cachedResults.get(0); } for (int j = 0; j < i; ++j) { if (FastMath.abs(crossingLine - crossingLineHistory[j]) <= 1.0) { @@ -413,11 +418,11 @@ public class SensorMeanPlaneCrossing { if (slowResult == null) { return null; } - for (int k = cachedResults.length - 1; k > 0; --k) { - cachedResults[k] = cachedResults[k - 1]; + if (cachedResults.size() >= CACHED_RESULTS) { + cachedResults.remove(cachedResults.size() - 1); } - cachedResults[0] = slowResult; - return cachedResults[0]; + cachedResults.add(0, slowResult); + return cachedResults.get(0); } } @@ -453,22 +458,23 @@ public class SensorMeanPlaneCrossing { } /** Guess a start line using the last four results. - * @param n number of cached results available * @param target target ground point * @return guessed start line */ - private double guessStartLine(final int n, final Vector3D target) { + private double guessStartLine(final Vector3D target) { try { // assume a linear model of the form: l = ax + by + cz + d + final int n = cachedResults.size(); final RealMatrix m = new Array2DRowRealMatrix(n, 4); final RealVector v = new ArrayRealVector(n); for (int i = 0; i < n; ++i) { - m.setEntry(i, 0, cachedResults[i].getTarget().getX()); - m.setEntry(i, 1, cachedResults[i].getTarget().getY()); - m.setEntry(i, 2, cachedResults[i].getTarget().getZ()); + final CrossingResult crossingResult = cachedResults.get(i); + m.setEntry(i, 0, crossingResult.getTarget().getX()); + m.setEntry(i, 1, crossingResult.getTarget().getY()); + m.setEntry(i, 2, crossingResult.getTarget().getZ()); m.setEntry(i, 3, 1.0); - v.setEntry(i, cachedResults[i].getLine()); + v.setEntry(i, crossingResult.getLine()); } final DecompositionSolver solver = new QRDecomposition(m, Precision.SAFE_MIN).getSolver();