From b0e0873e162f916ff01ac234279dfd31090ed27d Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Thu, 24 Apr 2014 09:39:27 +0200 Subject: [PATCH] Allow direct use of Orekit inertial frames and ellipsoids. --- .../java/org/orekit/rugged/api/Rugged.java | 284 +++++++++++------- 1 file changed, 177 insertions(+), 107 deletions(-) diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index 1fe99247..ab9c0791 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -28,6 +28,7 @@ import org.orekit.attitudes.Attitude; import org.orekit.attitudes.AttitudeProvider; import org.orekit.attitudes.TabulatedProvider; import org.orekit.bodies.GeodeticPoint; +import org.orekit.bodies.OneAxisEllipsoid; import org.orekit.errors.OrekitException; import org.orekit.frames.Frame; import org.orekit.frames.FramesFactory; @@ -58,7 +59,7 @@ public class Rugged { private final AbsoluteDate referenceDate; /** Inertial frame. */ - private final Frame frame; + private final Frame inertialFrame; /** Reference ellipsoid. */ private final ExtendedEllipsoid ellipsoid; @@ -108,30 +109,45 @@ public class Rugged { final int pvInterpolationOrder, final List<Pair<AbsoluteDate, Rotation>> quaternions, final int aInterpolationOrder) throws RuggedException { - try { - - // time reference - this.referenceDate = referenceDate; - - // space reference - frame = selectInertialFrame(inertialFrameID); - ellipsoid = selectEllipsoid(ellipsoidID, selectBodyRotatingFrame(bodyRotatingFrameID)); - - // orbit/attitude to body converter - final PVCoordinatesProvider pvProvider = selectPVCoordinatesProvider(positionsVelocities, pvInterpolationOrder); - final AttitudeProvider aProvider = selectAttitudeProvider(quaternions, aInterpolationOrder); - scToBody = new SpacecraftToObservedBody(frame, ellipsoid.getBodyFrame(), pvProvider, aProvider); - - // intersection algorithm - algorithm = selectAlgorithm(algorithmID, updater, maxCachedTiles); - - sensors = new HashMap<String, Sensor>(); - setLightTimeCorrection(true); - setAberrationOfLightCorrection(true); + this(referenceDate, updater, maxCachedTiles, algorithmID, + selectEllipsoid(ellipsoidID, selectBodyRotatingFrame(bodyRotatingFrameID)), + selectInertialFrame(inertialFrameID), + positionsVelocities, pvInterpolationOrder, quaternions, aInterpolationOrder); + } - } catch (OrekitException oe) { - throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); - } + /** Build a configured instance. + * <p> + * By default, the instance performs both light time correction (which refers + * to ground point motion with respect to inertial frame) and aberration of + * light correction (which refers to spacecraft proper velocity). Explicit calls + * to {@link #setLightTimeCorrection(boolean) setLightTimeCorrection} + * and {@link #setAberrationOfLightCorrection(boolean) setAberrationOfLightCorrection} + * can be made after construction if these phenomena should not be corrected. + * </p> + * @param referenceDate reference date from which all other dates are computed + * @param updater updater used to load Digital Elevation Model tiles + * @param maxCachedTiles maximum number of tiles stored in the cache + * @param algorithmID identifier of algorithm to use for Digital Elevation Model intersection + * @param ellipsoidID identifier of reference ellipsoid + * @param inertialFrameID identifier of inertial frame + * @param bodyRotatingFrameID identifier of body rotating frame + * @param positionsVelocities satellite position and velocity + * @param pvInterpolationOrder order to use for position/velocity interpolation + * @param quaternions satellite quaternions + * @param aInterpolationOrder order to use for attitude interpolation + * @exception RuggedException if data needed for some frame cannot be loaded + */ + public Rugged(final AbsoluteDate referenceDate, + final TileUpdater updater, final int maxCachedTiles, + final AlgorithmId algorithmID, final OneAxisEllipsoid ellipsoid, final Frame inertialFrame, + final List<Pair<AbsoluteDate, PVCoordinates>> positionsVelocities, + final int pvInterpolationOrder, final List<Pair<AbsoluteDate, Rotation>> quaternions, + final int aInterpolationOrder) + throws RuggedException { + this(referenceDate, updater, maxCachedTiles, algorithmID, + extend(ellipsoid), inertialFrame, + selectPVCoordinatesProvider(positionsVelocities, pvInterpolationOrder, inertialFrame), + selectAttitudeProvider(quaternions, aInterpolationOrder, inertialFrame)); } /** Build a configured instance. @@ -143,7 +159,7 @@ public class Rugged { * and {@link #setAberrationOfLightCorrection(boolean) setAberrationOfLightCorrection} * can be made after construction if these phenomena should not be corrected. * </p> - * @param newReferenceDate reference date from which all other dates are computed + * @param referenceDate reference date from which all other dates are computed * @param updater updater used to load Digital Elevation Model tiles * @param maxCachedTiles maximum number of tiles stored in the cache * @param algorithmID identifier of algorithm to use for Digital Elevation Model intersection @@ -153,35 +169,81 @@ public class Rugged { * @param propagator global propagator * @exception RuggedException if data needed for some frame cannot be loaded */ - public Rugged(final AbsoluteDate newReferenceDate, + public Rugged(final AbsoluteDate referenceDate, final TileUpdater updater, final int maxCachedTiles, final AlgorithmId algorithmID, final EllipsoidId ellipsoidID, final InertialFrameId inertialFrameID, final BodyRotatingFrameId bodyRotatingFrameID, final Propagator propagator) throws RuggedException { - try { + this(referenceDate, updater, maxCachedTiles, algorithmID, + selectEllipsoid(ellipsoidID, selectBodyRotatingFrame(bodyRotatingFrameID)), + selectInertialFrame(inertialFrameID), propagator); + } - // time reference - this.referenceDate = newReferenceDate; + /** Build a configured instance. + * <p> + * By default, the instance performs both light time correction (which refers + * to ground point motion with respect to inertial frame) and aberration of + * light correction (which refers to spacecraft proper velocity). Explicit calls + * to {@link #setLightTimeCorrection(boolean) setLightTimeCorrection} + * and {@link #setAberrationOfLightCorrection(boolean) setAberrationOfLightCorrection} + * can be made after construction if these phenomena should not be corrected. + * </p> + * @param referenceDate reference date from which all other dates are computed + * @param updater updater used to load Digital Elevation Model tiles + * @param maxCachedTiles maximum number of tiles stored in the cache + * @param algorithmID identifier of algorithm to use for Digital Elevation Model intersection + * @param ellipsoid f reference ellipsoid + * @param inertialFrame inertial frame + * @param bodyRotatingFrameID identifier of body rotating frame + * @param propagator global propagator + * @exception RuggedException if data needed for some frame cannot be loaded + */ + public Rugged(final AbsoluteDate referenceDate, + final TileUpdater updater, final int maxCachedTiles, + final AlgorithmId algorithmID, final OneAxisEllipsoid ellipsoid, + final Frame inertialFrame, final Propagator propagator) + throws RuggedException { + this(referenceDate, updater, maxCachedTiles, algorithmID, + extend(ellipsoid), inertialFrame, + propagator, propagator.getAttitudeProvider()); + } - // space reference - frame = selectInertialFrame(inertialFrameID); - ellipsoid = selectEllipsoid(ellipsoidID, selectBodyRotatingFrame(bodyRotatingFrameID)); + /** Low level private constructor. + * @param referenceDate reference date from which all other dates are computed + * @param updater updater used to load Digital Elevation Model tiles + * @param maxCachedTiles maximum number of tiles stored in the cache + * @param algorithmID identifier of algorithm to use for Digital Elevation Model intersection + * @param ellipsoid f reference ellipsoid + * @param inertialFrame inertial frame + * @param bodyRotatingFrameID identifier of body rotating frame + * @param pvProvider orbit propagator/interpolator + * @param aProvider attitude propagator/interpolator + * @exception RuggedException if data needed for some frame cannot be loaded + */ + private Rugged(final AbsoluteDate referenceDate, + final TileUpdater updater, final int maxCachedTiles, final AlgorithmId algorithmID, + final ExtendedEllipsoid ellipsoid, final Frame inertialFrame, + final PVCoordinatesProvider pvProvider, final AttitudeProvider aProvider) + throws RuggedException { - // orbit/attitude to body converter - scToBody = new SpacecraftToObservedBody(frame, ellipsoid.getBodyFrame(), - propagator, propagator.getAttitudeProvider()); + // time reference + this.referenceDate = referenceDate; - // intersection algorithm - algorithm = selectAlgorithm(algorithmID, updater, maxCachedTiles); + // space reference + this.inertialFrame = inertialFrame; + this.ellipsoid = ellipsoid; - sensors = new HashMap<String, Sensor>(); - setLightTimeCorrection(true); - setAberrationOfLightCorrection(true); + // orbit/attitude to body converter + this.scToBody = new SpacecraftToObservedBody(inertialFrame, ellipsoid.getBodyFrame(), pvProvider, aProvider); + + // intersection algorithm + this.algorithm = selectAlgorithm(algorithmID, updater, maxCachedTiles); + + this.sensors = new HashMap<String, Sensor>(); + setLightTimeCorrection(true); + setAberrationOfLightCorrection(true); - } catch (OrekitException oe) { - throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); - } } /** Get the reference date. @@ -261,28 +323,32 @@ public class Rugged { } /** Select inertial frame. - * @param inertialFrame inertial frame identifier + * @param inertialFrameId inertial frame identifier * @return inertial frame - * @exception OrekitException if data needed for some frame cannot be loaded + * @exception RuggedException if data needed for some frame cannot be loaded */ - private Frame selectInertialFrame(final InertialFrameId inertialFrame) - throws OrekitException { - - // set up the inertial frame - switch (inertialFrame) { - case GCRF : - return FramesFactory.getGCRF(); - case EME2000 : - return FramesFactory.getEME2000(); - case MOD : - return FramesFactory.getMOD(IERSConventions.IERS_1996); - case TOD : - return FramesFactory.getTOD(IERSConventions.IERS_1996, true); - case VEIS1950 : - return FramesFactory.getVeis1950(); - default : - // this should never happen - throw RuggedException.createInternalError(null); + private static Frame selectInertialFrame(final InertialFrameId inertialFrameId) + throws RuggedException { + + try { + // set up the inertial frame + switch (inertialFrameId) { + case GCRF : + return FramesFactory.getGCRF(); + case EME2000 : + return FramesFactory.getEME2000(); + case MOD : + return FramesFactory.getMOD(IERSConventions.IERS_1996); + case TOD : + return FramesFactory.getTOD(IERSConventions.IERS_1996, true); + case VEIS1950 : + return FramesFactory.getVeis1950(); + default : + // this should never happen + throw RuggedException.createInternalError(null); + } + } catch (OrekitException oe) { + throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); } } @@ -290,22 +356,26 @@ public class Rugged { /** Select body rotating frame. * @param bodyRotatingFrame body rotating frame identifier * @return body rotating frame - * @exception OrekitException if data needed for some frame cannot be loaded + * @exception RuggedException if data needed for some frame cannot be loaded */ - private Frame selectBodyRotatingFrame(final BodyRotatingFrameId bodyRotatingFrame) - throws OrekitException { - - // set up the rotating frame - switch (bodyRotatingFrame) { - case ITRF : - return FramesFactory.getITRF(IERSConventions.IERS_2010, true); - case ITRF_EQUINOX : - return FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true); - case GTOD : - return FramesFactory.getGTOD(IERSConventions.IERS_1996, true); - default : - // this should never happen - throw RuggedException.createInternalError(null); + private static Frame selectBodyRotatingFrame(final BodyRotatingFrameId bodyRotatingFrame) + throws RuggedException { + + try { + // set up the rotating frame + switch (bodyRotatingFrame) { + case ITRF : + return FramesFactory.getITRF(IERSConventions.IERS_2010, true); + case ITRF_EQUINOX : + return FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true); + case GTOD : + return FramesFactory.getGTOD(IERSConventions.IERS_1996, true); + default : + // this should never happen + throw RuggedException.createInternalError(null); + } + } catch (OrekitException oe) { + throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); } } @@ -314,23 +384,21 @@ public class Rugged { * @param ellipsoidID reference ellipsoid identifier * @param bodyFrame body rotating frame * @return selected ellipsoid - * @exception OrekitException if data needed for some frame cannot be loaded */ - private ExtendedEllipsoid selectEllipsoid(final EllipsoidId ellipsoidID, final Frame bodyFrame) - throws OrekitException { + private static OneAxisEllipsoid selectEllipsoid(final EllipsoidId ellipsoidID, final Frame bodyFrame) { // set up the ellipsoid switch (ellipsoidID) { case GRS80 : - return new ExtendedEllipsoid(6378137.0, 1.0 / 298.257222101, bodyFrame); + return new OneAxisEllipsoid(6378137.0, 1.0 / 298.257222101, bodyFrame); case WGS84 : - return new ExtendedEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, - Constants.WGS84_EARTH_FLATTENING, - bodyFrame); + return new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, + Constants.WGS84_EARTH_FLATTENING, + bodyFrame); case IERS96 : - return new ExtendedEllipsoid(6378136.49, 1.0 / 298.25645, bodyFrame); + return new OneAxisEllipsoid(6378136.49, 1.0 / 298.25645, bodyFrame); case IERS2003 : - return new ExtendedEllipsoid(6378136.6, 1.0 / 298.25642, bodyFrame); + return new OneAxisEllipsoid(6378136.6, 1.0 / 298.25642, bodyFrame); default : // this should never happen throw RuggedException.createInternalError(null); @@ -338,20 +406,29 @@ public class Rugged { } + /** Convert a {@link OneAxisEllipsoid} into a {@link ExtendedEllipsoid} + * @param ellipsoid ellpsoid to extend + * @return extended ellipsoid + */ + private static ExtendedEllipsoid extend(final OneAxisEllipsoid ellipsoid) { + return new ExtendedEllipsoid(ellipsoid.getEquatorialRadius(), + ellipsoid.getFlattening(), + ellipsoid.getBodyFrame()); + } + /** Select attitude provider. * @param quaternions satellite quaternions * @param interpolationOrder order to use for interpolation + * @param inertialFrame inertial frame where position and velocity are defined * @return selected attitude provider - * @exception OrekitException if data needed for some frame cannot be loaded */ - private AttitudeProvider selectAttitudeProvider(final List<Pair<AbsoluteDate, Rotation>> quaternions, - final int interpolationOrder) - throws OrekitException { + private static AttitudeProvider selectAttitudeProvider(final List<Pair<AbsoluteDate, Rotation>> quaternions, + final int interpolationOrder, final Frame inertialFrame) { // set up the attitude provider final List<Attitude> attitudes = new ArrayList<Attitude>(quaternions.size()); for (final Pair<AbsoluteDate, Rotation> q : quaternions) { - attitudes.add(new Attitude(q.getFirst(), frame, q.getSecond(), Vector3D.ZERO)); + attitudes.add(new Attitude(q.getFirst(), inertialFrame, q.getSecond(), Vector3D.ZERO)); } return new TabulatedProvider(attitudes, interpolationOrder, false); @@ -360,17 +437,16 @@ public class Rugged { /** Select position/velocity provider. * @param positionsVelocities satellite position and velocity * @param interpolationOrder order to use for interpolation + * @param inertialFrame inertial frame where position and velocity are defined * @return selected position/velocity provider - * @exception OrekitException if data needed for some frame cannot be loaded */ - private PVCoordinatesProvider selectPVCoordinatesProvider(final List<Pair<AbsoluteDate, PVCoordinates>> positionsVelocities, - final int interpolationOrder) - throws OrekitException { + private static PVCoordinatesProvider selectPVCoordinatesProvider(final List<Pair<AbsoluteDate, PVCoordinates>> positionsVelocities, + final int interpolationOrder, final Frame inertialFrame) { // set up the ephemeris final List<Orbit> orbits = new ArrayList<Orbit>(positionsVelocities.size()); for (final Pair<AbsoluteDate, PVCoordinates> pv : positionsVelocities) { - final CartesianOrbit orbit = new CartesianOrbit(pv.getSecond(), frame, pv.getFirst(), Constants.EIGEN5C_EARTH_MU); + final CartesianOrbit orbit = new CartesianOrbit(pv.getSecond(), inertialFrame, pv.getFirst(), Constants.EIGEN5C_EARTH_MU); orbits.add(orbit); } @@ -381,7 +457,7 @@ public class Rugged { /** {@inhritDoc} */ @Override public PVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame f) - throws OrekitException { + throws OrekitException { final List<Orbit> sample = cache.getNeighbors(date); final Orbit interpolated = sample.get(0).interpolate(date, sample); return interpolated.getPVCoordinates(date, f); @@ -419,10 +495,7 @@ public class Rugged { * @param sensorName name of the line sensor * @param lineNumber number of the line to localize on ground * @return ground position of all pixels of the specified sensor line - * @exception RuggedException if line cannot be localized, - * if {@link #setGeneralContext(File, InertialFrame, BodyRotatingFrame, Ellipsoid)} has - * not been called beforehand, or if {@link #setOrbitAndAttitude(List, List)} has not - * been called beforehand, or sensor is unknown + * @exception RuggedException if line cannot be localized, or sensor is unknown */ public GeodeticPoint[] directLocalization(final String sensorName, final double lineNumber) throws RuggedException { @@ -490,10 +563,7 @@ public class Rugged { * @param sensorName name of the line sensor * @param groundPoint ground point to localize * @return sensor pixel seeing ground point - * @exception RuggedException if line cannot be localized, - * if {@link #setGeneralContext(File, InertialFrame, BodyRotatingFrame, Ellipsoid)} has - * not been called beforehand, or if {@link #setOrbitAndAttitude(List, List)} has not - * been called beforehand, or sensor is unknown + * @exception RuggedException if line cannot be localized, or sensor is unknown */ public SensorPixel inverseLocalization(final String sensorName, final GeodeticPoint groundPoint) throws RuggedException { @@ -510,7 +580,7 @@ public class Rugged { * @exception RuggedException if context has not been initialized */ private void checkContext() throws RuggedException { - if (frame == null) { + if (inertialFrame == null) { throw new RuggedException(RuggedMessages.UNINITIALIZED_CONTEXT); } } -- GitLab