diff --git a/src/main/java/org/orekit/rugged/api/RuggedBuilder.java b/src/main/java/org/orekit/rugged/api/RuggedBuilder.java index e5423c847bbcc7f47409452f0e37cced0e29957b..534f77374f1df049b4db63fdc0ce78c34f33452b 100644 --- a/src/main/java/org/orekit/rugged/api/RuggedBuilder.java +++ b/src/main/java/org/orekit/rugged/api/RuggedBuilder.java @@ -96,16 +96,16 @@ public class RuggedBuilder { private int maxCachedTiles; /** Start of search time span. */ - private AbsoluteDate startDate; + private AbsoluteDate minDate; /** End of search time span. */ - private AbsoluteDate endDate; + private AbsoluteDate maxDate; /** Step to use for inertial frame to body frame transforms cache computations. */ - private double step; + private double tStep; /** OvershootTolerance tolerance in seconds allowed for {@code minDate} and {@code maxDate} overshooting. */ - private double tolerance; + private double overshootTolerance; /** Inertial frame for position/velocity/attitude. */ private Frame inertial; @@ -166,7 +166,7 @@ public class RuggedBuilder { * @param ellipsoidID reference ellipsoid * @param bodyRotatingFrameID body rotating frame identifier * @exception RuggedException if data needed for some frame cannot be loaded - * or if trajectory has been {@link #setTrajectory(InputStream) recovered} + * or if trajectory has been {@link #setTrajectoryAndTimeSpan(InputStream) recovered} * from an earlier run and frames mismatch * @return the builder instance * @see #setEllipsoid(OneAxisEllipsoid) @@ -181,7 +181,7 @@ public class RuggedBuilder { * @return the builder instance * @see #setEllipsoid(EllipsoidId, BodyRotatingFrameId) * @exception RuggedException if trajectory has been - * {@link #setTrajectory(InputStream) recovered} from an earlier run and frames + * {@link #setTrajectoryAndTimeSpan(InputStream) recovered} from an earlier run and frames * mismatch */ // CHECKSTYLE: stop HiddenField check @@ -234,22 +234,39 @@ public class RuggedBuilder { } /** Set the time span to be covered for direct and inverse location calls. + * <p> + * This method set only the time span and not the trajectory, therefore it + * <em>must</em> be used together with either + * {@link #setTrajectory(InertialFrameId, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter)}, + * {@link #setTrajectory(Frame, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter)}, + * or {@link #setTrajectory(double, int, CartesianDerivativesFilter, AngularDerivativesFilter, Propagator)} + * but should <em>not</em> be mixed with {@link #setTrajectoryAndTimeSpan(InputStream)}. + * </p> * @param minDate start of search time span * @param maxDate end of search time span * @param tStep step to use for inertial frame to body frame transforms cache computations * @param overshootTolerance tolerance in seconds allowed for {@code minDate} and {@code maxDate} overshooting * @return the builder instance + * @see #setTrajectoryAndTimeSpan(InputStream) */ + // CHECKSTYLE: stop HiddenField check public RuggedBuilder setTimeSpan(final AbsoluteDate minDate, final AbsoluteDate maxDate, final double tStep, final double overshootTolerance) { - this.startDate = minDate; - this.endDate = maxDate; - this.step = tStep; - this.tolerance = overshootTolerance; + // CHECKSTYLE: resume HiddenField check + this.minDate = minDate; + this.maxDate = maxDate; + this.tStep = tStep; + this.overshootTolerance = overshootTolerance; + this.scToBody = null; return this; } /** Set the spacecraft trajectory. + * <p> + * This method set only the trajectory and not the time span, therefore it + * <em>must</em> be used together with the {@link #setTimeSpan(AbsoluteDate, AbsoluteDate, double, double)} + * but should <em>not</em> be mixed with {@link #setTrajectoryAndTimeSpan(InputStream)}. + * </p> * @param inertialFrame inertial frame used for spacecraft positions/velocities/quaternions * @param positionsVelocities satellite position and velocity (m and m/s in inertial frame) * @param pvInterpolationNumber number of points to use for position/velocity interpolation @@ -261,7 +278,7 @@ public class RuggedBuilder { * @exception RuggedException if data needed for inertial frame cannot be loaded * @see #setTrajectory(Frame, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter) * @see #setTrajectory(double, int, CartesianDerivativesFilter, AngularDerivativesFilter, Propagator) - * @see #setTrajectory(InputStream) + * @see #setTrajectoryAndTimeSpan(InputStream) */ public RuggedBuilder setTrajectory(final InertialFrameId inertialFrame, final List<TimeStampedPVCoordinates> positionsVelocities, final int pvInterpolationNumber, @@ -275,6 +292,11 @@ public class RuggedBuilder { } /** Set the spacecraft trajectory. + * <p> + * This method set only the trajectory and not the time span, therefore it + * <em>must</em> be used together with the {@link #setTimeSpan(AbsoluteDate, AbsoluteDate, double, double)} + * but should <em>not</em> be mixed with {@link #setTrajectoryAndTimeSpan(InputStream)}. + * </p> * @param inertialFrame inertial frame used for spacecraft positions/velocities/quaternions * @param positionsVelocities satellite position and velocity (m and m/s in inertial frame) * @param pvInterpolationNumber number of points to use for position/velocity interpolation @@ -285,7 +307,7 @@ public class RuggedBuilder { * @return the builder instance * @see #setTrajectory(InertialFrameId, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter) * @see #setTrajectory(double, int, CartesianDerivativesFilter, AngularDerivativesFilter, Propagator) - * @see #setTrajectory(InputStream) + * @see #setTrajectoryAndTimeSpan(InputStream) */ public RuggedBuilder setTrajectory(final Frame inertialFrame, final List<TimeStampedPVCoordinates> positionsVelocities, final int pvInterpolationNumber, @@ -307,6 +329,11 @@ public class RuggedBuilder { } /** Set the spacecraft trajectory. + * <p> + * This method set only the trajectory and not the time span, therefore it + * <em>must</em> be used together with the {@link #setTimeSpan(AbsoluteDate, AbsoluteDate, double, double)} + * but should <em>not</em> be mixed with {@link #setTrajectoryAndTimeSpan(InputStream)}. + * </p> * @param interpolationStep step to use for inertial/Earth/spacraft transforms interpolations * @param interpolationNumber number of points to use for inertial/Earth/spacraft transforms interpolations * @param pvFilter filter for derivatives from the sample to use in position/velocity interpolation @@ -315,7 +342,7 @@ public class RuggedBuilder { * @return the builder instance * @see #setTrajectory(InertialFrameId, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter) * @see #setTrajectory(Frame, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter) - * @see #setTrajectory(InputStream) + * @see #setTrajectoryAndTimeSpan(InputStream) */ public RuggedBuilder setTrajectory(final double interpolationStep, final int interpolationNumber, final CartesianDerivativesFilter pvFilter, final AngularDerivativesFilter aFilter, @@ -334,7 +361,15 @@ public class RuggedBuilder { return this; } - /** Set the spacecraft trajectory. + /** Set both the spacecraft trajectory and the time span. + * <p> + * This method set both the trajectory and the time span in a tightly coupled + * way, therefore it should <em>not</em> be mixed with the individual methods + * {@link #setTrajectory(double, int, CartesianDerivativesFilter, AngularDerivativesFilter, Propagator)}, + * {@link #setTrajectory(Frame, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter)}, + * {@link #setTrajectory(InertialFrameId, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter)}, + * or {@link #setTimeSpan(AbsoluteDate, AbsoluteDate, double, double)}. + * </p> * @param dumpStream stream from where to read previous instance dumped interpolator * (caller opened it and remains responsible for closing it) * @return the builder instance @@ -345,20 +380,24 @@ public class RuggedBuilder { * @see #setTrajectory(double, int, CartesianDerivativesFilter, AngularDerivativesFilter, Propagator) * @see #dumpInterpolator(OutputStream) */ - public RuggedBuilder setTrajectory(final InputStream dumpStream) + public RuggedBuilder setTrajectoryAndTimeSpan(final InputStream dumpStream) throws RuggedException { try { - this.inertial = null; - this.pvSample = null; - this.pvNeighborsSize = -1; - this.pvDerivatives = null; - this.aSample = null; - this.aNeighborsSize = -1; - this.aDerivatives = null; - this.pvaPropagator = null; - this.iStep = Double.NaN; - this.iN = -1; - this.scToBody = (SpacecraftToObservedBody) new ObjectInputStream(dumpStream).readObject(); + this.inertial = null; + this.pvSample = null; + this.pvNeighborsSize = -1; + this.pvDerivatives = null; + this.aSample = null; + this.aNeighborsSize = -1; + this.aDerivatives = null; + this.pvaPropagator = null; + this.iStep = Double.NaN; + this.iN = -1; + this.scToBody = (SpacecraftToObservedBody) new ObjectInputStream(dumpStream).readObject(); + this.minDate = scToBody.getMinDate(); + this.maxDate = scToBody.getMaxDate(); + this.tStep = scToBody.getTStep(); + this.overshootTolerance = scToBody.getOvershootTolerance(); checkFramesConsistency(); return this; } catch (ClassNotFoundException cnfe) { @@ -373,7 +412,7 @@ public class RuggedBuilder { /** Dump frames transform interpolator. * <p> * This method allows to reuse the interpolator built in one instance, to build - * another instance by calling {@link #setTrajectory(InputStream)}. + * another instance by calling {@link #setTrajectoryAndTimeSpan(InputStream)}. * This reduces the builder initialization time as setting up the interpolator can be long, it is * mainly intended to be used when several runs are done (for example in an image processing chain) * with the same configuration. @@ -389,7 +428,7 @@ public class RuggedBuilder { * @see #setTrajectory(InertialFrameId, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter) * @see #setTrajectory(Frame, List, int, CartesianDerivativesFilter, List, int, AngularDerivativesFilter) * @see #setTrajectory(double, int, CartesianDerivativesFilter, AngularDerivativesFilter, Propagator) - * @see #setTrajectory(InputStream) + * @see #setTrajectoryAndTimeSpan(InputStream) */ public void dumpInterpolator(final OutputStream dumpStream) throws RuggedException { try { @@ -426,12 +465,12 @@ public class RuggedBuilder { if (scToBody == null) { if (pvSample != null) { scToBody = createInterpolator(inertial, ellipsoid.getBodyFrame(), - startDate, endDate, step, tolerance, + minDate, maxDate, tStep, overshootTolerance, pvSample, pvNeighborsSize, pvDerivatives, aSample, aNeighborsSize, aDerivatives); } else if (pvaPropagator != null) { scToBody = createInterpolator(inertial, ellipsoid.getBodyFrame(), - startDate, endDate, step, tolerance, + minDate, maxDate, tStep, overshootTolerance, iStep, iN, pvDerivatives, aDerivatives, pvaPropagator); } else { throw new RuggedException(RuggedMessages.UNINITIALIZED_CONTEXT, "RuggedBuilder.setTrajectory()"); @@ -468,8 +507,8 @@ public class RuggedBuilder { final AngularDerivativesFilter aFilter) throws RuggedException { return new SpacecraftToObservedBody(inertialFrame, bodyFrame, - minDate, maxDate, tStep, - overshootTolerance, positionsVelocities, pvInterpolationNumber, + minDate, maxDate, tStep, overshootTolerance, + positionsVelocities, pvInterpolationNumber, pvFilter, quaternions, aInterpolationNumber, aFilter); } @@ -531,8 +570,8 @@ public class RuggedBuilder { // orbit/attitude to body converter return createInterpolator(inertialFrame, bodyFrame, - minDate, maxDate, tStep, - overshootTolerance, positionsVelocities, interpolationNumber, + minDate, maxDate, tStep, overshootTolerance, + positionsVelocities, interpolationNumber, pvFilter, quaternions, interpolationNumber, aFilter); @@ -596,6 +635,14 @@ public class RuggedBuilder { return this; } + /** Remove all line sensors. + * @return the builder instance + */ + public RuggedBuilder clearLineSensors() { + sensors.clear(); + return this; + } + /** Select inertial frame. * @param inertialFrameId inertial frame identifier * @return inertial frame diff --git a/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java b/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java index 0d706bdd80fea1f88237da7605dc4c532aee3b9f..5ce80bad68b4f4cb060298d33dac579c34850e2c 100644 --- a/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java +++ b/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java @@ -210,6 +210,20 @@ public class SpacecraftToObservedBody implements Serializable { return maxDate; } + /** Get the step to use for inertial frame to body frame transforms cache computations. + * @return step to use for inertial frame to body frame transforms cache computations + */ + public double getTStep() { + return tStep; + } + + /** Get the tolerance in seconds allowed for {@link #getMinDate()} and {@link #getMaxDate()} overshooting. + * @return tolerance in seconds allowed for {@link #getMinDate()} and {@link #getMaxDate()} overshooting + */ + public double getOvershootTolerance() { + return overshootTolerance; + } + /** Get transform from spacecraft to inertial frame. * @param date date of the transform * @return transform from spacecraft to inertial frame diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index 7a6d533fe772e038e1d70d56e4407d28d5adfbef..cddfc535e516380a9e905525d779e8ea6b9cb6f4 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -22,6 +22,9 @@ <body> <release version="1.0" date="TBD" description="TBD"> + <action dev="luc" type="fix" > + Force reset of builder interpolator when time span is changed. + </action> <action dev="luc" type="add" due-to="Lucian Barbulescu"> Added Romanian translation of error messages. </action> diff --git a/src/test/java/org/orekit/rugged/api/RuggedBuilderTest.java b/src/test/java/org/orekit/rugged/api/RuggedBuilderTest.java index dc6d83db9c42327251df3ade5ae912c755190d65..175cbc16480b868dd54cdd624adb8fe2ff89b591 100644 --- a/src/test/java/org/orekit/rugged/api/RuggedBuilderTest.java +++ b/src/test/java/org/orekit/rugged/api/RuggedBuilderTest.java @@ -373,7 +373,7 @@ public class RuggedBuilderTest { setDigitalElevationModel(updater, 8). setAlgorithm(AlgorithmId.DUVENHAGE). setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF). - setTrajectory(new ByteArrayInputStream(bos.toByteArray())). + setTrajectoryAndTimeSpan(new ByteArrayInputStream(bos.toByteArray())). addLineSensor(lineSensor); GeodeticPoint[] gpRecovered = recovered.build().directLocation("line", 100); @@ -485,7 +485,7 @@ public class RuggedBuilderTest { new RuggedBuilder(). setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID). setEllipsoid(EllipsoidId.WGS84, bId). - setTrajectory(new ByteArrayInputStream(bos.toByteArray())).build(); + setTrajectoryAndTimeSpan(new ByteArrayInputStream(bos.toByteArray())).build(); Assert.fail("an exception should have been thrown"); } catch (RuggedException re) { Assert.assertEquals(RuggedMessages.FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP, @@ -546,7 +546,7 @@ public class RuggedBuilderTest { for (byte[] array : Arrays.asList(nonExistentClass, integerOne, truncatedDump, notSerialization)) { try { - new RuggedBuilder().setTrajectory(new ByteArrayInputStream(array)); + new RuggedBuilder().setTrajectoryAndTimeSpan(new ByteArrayInputStream(array)); Assert.fail("an exception should have been thrown"); } catch (RuggedException re) { Assert.assertEquals(RuggedMessages.NOT_INTERPOLATOR_DUMP_DATA,