diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index a38a2798a4be7e3457b1392aeb01c0e262149704..ab77fe3e62f517282b910267297c297491bc3338 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -17,18 +17,67 @@ package org.orekit.rugged.api; import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.commons.math3.geometry.euclidean.threed.Rotation; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.util.Pair; +import org.orekit.attitudes.Attitude; +import org.orekit.attitudes.AttitudeProvider; +import org.orekit.attitudes.TabulatedProvider; import org.orekit.bodies.GeodeticPoint; +import org.orekit.errors.OrekitException; +import org.orekit.frames.Frame; +import org.orekit.frames.FramesFactory; +import org.orekit.frames.Transform; +import org.orekit.orbits.CartesianOrbit; +import org.orekit.orbits.Orbit; +import org.orekit.propagation.Propagator; +import org.orekit.rugged.core.BasicScanAlgorithm; +import org.orekit.rugged.core.ExtendedEllipsoid; +import org.orekit.rugged.core.IgnoreDEMAlgorithm; +import org.orekit.rugged.core.Sensor; +import org.orekit.rugged.core.SpacecraftToObservedBody; +import org.orekit.rugged.core.duvenhage.DuvenhageAlgorithm; +import org.orekit.rugged.core.raster.IntersectionAlgorithm; import org.orekit.time.AbsoluteDate; +import org.orekit.utils.Constants; +import org.orekit.utils.IERSConventions; +import org.orekit.utils.ImmutableTimeStampedCache; import org.orekit.utils.PVCoordinates; +import org.orekit.utils.PVCoordinatesProvider; -/** Main interface to Rugged library. +/** Main class of Rugged library API. * @author Luc Maisonobe */ -public interface Rugged { +public class Rugged { + + /** Reference date. */ + private AbsoluteDate referenceDate; + + /** Inertial frame. */ + private Frame frame; + + /** Reference ellipsoid. */ + private ExtendedEllipsoid ellipsoid; + + /** Converter between spacecraft and body. */ + private SpacecraftToObservedBody scToBody; + + /** Sensors. */ + private final Map<String, Sensor> sensors; + + /** DEM intersection algorithm. */ + private IntersectionAlgorithm algorithm; + + /** Simple constructor. + */ + protected Rugged() { + sensors = new HashMap<String, Sensor>(); + } /** Set up general context. * <p> @@ -47,25 +96,257 @@ public interface Rugged { * @param aInterpolationOrder order to use for attitude interpolation * @exception RuggedException if data needed for some frame cannot be loaded */ - void setGeneralContext(AbsoluteDate referenceDate, - AlgorithmId algorithmID, EllipsoidId ellipsoidID, - InertialFrameId inertialFrameID, BodyRotatingFrameId bodyRotatingFrameID, - List<Pair<AbsoluteDate, PVCoordinates>> positionsVelocities, int pvInterpolationOrder, - List<Pair<AbsoluteDate, Rotation>> quaternions, int aInterpolationOrder) - throws RuggedException; + public void setGeneralContext(final AbsoluteDate newReferenceDate, + final AlgorithmId algorithmID, final EllipsoidId ellipsoidID, + final InertialFrameId inertialFrameID, + final BodyRotatingFrameId bodyRotatingFrameID, + final List<Pair<AbsoluteDate, PVCoordinates>> positionsVelocities, final int pvInterpolationOrder, + final List<Pair<AbsoluteDate, Rotation>> quaternions, final int aInterpolationOrder) + throws RuggedException { + try { + + // time reference + this.referenceDate = newReferenceDate; + + // 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); + + } catch (OrekitException oe) { + throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); + } + } + + /** Set up general context. + * <p> + * This method is the first one that must be called, otherwise the + * other methods will fail due to uninitialized context. + * </p> + * @param newReferenceDate reference date from which all other dates are computed + * @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 propagator global propagator + * @exception RuggedException if data needed for some frame cannot be loaded + */ + public void setGeneralContext(final AbsoluteDate newReferenceDate, + final AlgorithmId algorithmID, final EllipsoidId ellipsoidID, + final InertialFrameId inertialFrameID, + final BodyRotatingFrameId bodyRotatingFrameID, + final Propagator propagator) + throws RuggedException { + try { + + // time reference + this.referenceDate = newReferenceDate; + + // space reference + frame = selectInertialFrame(inertialFrameID); + ellipsoid = selectEllipsoid(ellipsoidID, selectBodyRotatingFrame(bodyRotatingFrameID)); + + // orbit/attitude to body converter + scToBody = new SpacecraftToObservedBody(frame, ellipsoid.getBodyFrame(), + propagator, propagator.getAttitudeProvider()); + + // intersection algorithm + algorithm = selectAlgorithm(algorithmID); + + } catch (OrekitException oe) { + throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); + } + } + + /** Get the reference date. + * @return reference date + */ + public AbsoluteDate getReferenceDate() { + return referenceDate; + } /** Set up the tiles management. * @param updater updater used to load Digital Elevation Model tiles * @param maxCachedTiles maximum number of tiles stored in the cache */ - void setUpTilesManagement(TileUpdater updater, int maxCachedTiles); + public void setUpTilesManagement(final TileUpdater updater, final int maxCachedTiles) { + algorithm.setUpTilesManagement(updater, maxCachedTiles); + } /** Set up line sensor model. * @param name name of the line sensor. * @param pixels lines of sight for each pixels * @param datationModel model to use for dating sensor lines */ - void setLineSensor(String name, List<PixelLOS> pixels, LineDatation datationModel); + public void setLineSensor(final String sensorName, final List<PixelLOS> linesOfSigth, final LineDatation datationModel) { + final List<Vector3D> positions = new ArrayList<Vector3D>(linesOfSigth.size()); + final List<Vector3D> los = new ArrayList<Vector3D>(linesOfSigth.size()); + for (final PixelLOS plos : linesOfSigth) { + positions.add(new Vector3D(plos.getPx(), plos.getPy(), plos.getPz())); + los.add(new Vector3D(plos.getDx(), plos.getDy(), plos.getDz())); + } + final Sensor sensor = new Sensor(sensorName, referenceDate, datationModel, positions, los); + sensors.put(sensor.getName(), sensor); + } + + /** Select inertial frame. + * @param inertialFrame inertial frame identifier + * @return inertial frame + * @exception OrekitException 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); + } + + } + + /** 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 + */ + 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); + } + + } + + /** Select ellipsoid. + * @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 { + + // set up the ellipsoid + switch (ellipsoidID) { + case GRS80 : + return new ExtendedEllipsoid(6378137.0, 1.0 / 298.257222101, bodyFrame); + case WGS84 : + return new ExtendedEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, + Constants.WGS84_EARTH_FLATTENING, + bodyFrame); + case IERS96 : + return new ExtendedEllipsoid(6378136.49, 1.0 / 298.25645, bodyFrame); + case IERS2003 : + return new ExtendedEllipsoid(6378136.6, 1.0 / 298.25642, bodyFrame); + default : + // this should never happen + throw RuggedException.createInternalError(null); + } + + } + + /** Select attitude provider. + * @param quaternions satellite quaternions + * @param interpolationOrder order to use for interpolation + * @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 { + + // 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)); + } + return new TabulatedProvider(attitudes, interpolationOrder, false); + + } + + /** Select position/velocity provider. + * @param positionsVelocities satellite position and velocity + * @param interpolationOrder order to use for interpolation + * @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 { + + // 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); + orbits.add(orbit); + } + + final ImmutableTimeStampedCache<Orbit> cache = + new ImmutableTimeStampedCache<Orbit>(interpolationOrder, orbits); + return new PVCoordinatesProvider() { + + /** {@inhritDoc} */ + @Override + public PVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame f) + throws OrekitException { + final List<Orbit> sample = cache.getNeighbors(date); + final Orbit interpolated = sample.get(0).interpolate(date, sample); + return interpolated.getPVCoordinates(date, f); + } + + }; + + } + + /** Select DEM intersection algorithm. + * @param algorithmID intersection algorithm identifier + * @return selected algorithm + */ + private IntersectionAlgorithm selectAlgorithm(final AlgorithmId algorithmID) { + + // set up the algorithm + switch (algorithmID) { + case DUVENHAGE : + return new DuvenhageAlgorithm(); + case BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY : + return new BasicScanAlgorithm(); + case IGNORE_DEM_USE_ELLIPSOID : + return new IgnoreDEMAlgorithm(); + default : + // this should never happen + throw RuggedException.createInternalError(null); + } + + } /** Direct localization of a sensor line. * @param name name of the line sensor @@ -76,8 +357,43 @@ public interface Rugged { * not been called beforehand, or if {@link #setOrbitAndAttitude(List, List)} has not * been called beforehand, or sensor is unknown */ - GeodeticPoint[] directLocalization(String name, double lineNumber) - throws RuggedException; + public GeodeticPoint[] directLocalization(final String sensorName, final double lineNumber) + throws RuggedException { + try { + + checkContext(); + + // select the sensor + final Sensor sensor = getSensor(sensorName); + + // 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 GeodeticPoint[] gp = new GeodeticPoint[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)); + + gp[i] = algorithm.intersection(ellipsoid, + fixed.transformPosition(sensor.getPosition(i)), + fixed.transformVector(sensor.getLos(i))); + } + + return gp; + + } catch (OrekitException oe) { + throw new RuggedException(oe, oe.getSpecifier(), oe.getParts()); + } + } /** Inverse localization of a ground point. * @param name name of the line sensor @@ -88,7 +404,37 @@ public interface Rugged { * not been called beforehand, or if {@link #setOrbitAndAttitude(List, List)} has not * been called beforehand, or sensor is unknown */ - SensorPixel inverseLocalization(String name, GeodeticPoint groundPoint) - throws RuggedException; + public SensorPixel inverseLocalization(final String sensorName, final GeodeticPoint groundPoint) + throws RuggedException { + + checkContext(); + final Sensor sensor = getSensor(sensorName); + + // TODO: implement direct localization + throw RuggedException.createInternalError(null); + + } + + /** Check if context has been initialized. + * @exception RuggedException if context has not been initialized + */ + private void checkContext() throws RuggedException { + if (frame == null) { + throw new RuggedException(RuggedMessages.UNINITIALIZED_CONTEXT); + } + } + + /** Get a sensor. + * @param sensorName sensor name + * @return selected sensor + * @exception RuggedException if sensor is not known + */ + private Sensor getSensor(final String sensorName) throws RuggedException { + final Sensor sensor = sensors.get(sensorName); + if (sensor == null) { + throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName); + } + return sensor; + } } diff --git a/src/main/java/org/orekit/rugged/core/RuggedImpl.java b/src/main/java/org/orekit/rugged/core/RuggedImpl.java deleted file mode 100644 index 8a37a610637a159b572c3b67312fe19855ed9a92..0000000000000000000000000000000000000000 --- a/src/main/java/org/orekit/rugged/core/RuggedImpl.java +++ /dev/null @@ -1,411 +0,0 @@ -/* 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.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.math3.geometry.euclidean.threed.Rotation; -import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; -import org.apache.commons.math3.util.Pair; -import org.orekit.attitudes.Attitude; -import org.orekit.attitudes.AttitudeProvider; -import org.orekit.attitudes.TabulatedProvider; -import org.orekit.bodies.GeodeticPoint; -import org.orekit.errors.OrekitException; -import org.orekit.frames.Frame; -import org.orekit.frames.FramesFactory; -import org.orekit.frames.Transform; -import org.orekit.orbits.CartesianOrbit; -import org.orekit.orbits.Orbit; -import org.orekit.propagation.Propagator; -import org.orekit.rugged.api.AlgorithmId; -import org.orekit.rugged.api.BodyRotatingFrameId; -import org.orekit.rugged.api.EllipsoidId; -import org.orekit.rugged.api.InertialFrameId; -import org.orekit.rugged.api.LineDatation; -import org.orekit.rugged.api.PixelLOS; -import org.orekit.rugged.api.Rugged; -import org.orekit.rugged.api.RuggedException; -import org.orekit.rugged.api.RuggedMessages; -import org.orekit.rugged.api.SensorPixel; -import org.orekit.rugged.api.TileUpdater; -import org.orekit.rugged.core.duvenhage.DuvenhageAlgorithm; -import org.orekit.rugged.core.raster.IntersectionAlgorithm; -import org.orekit.time.AbsoluteDate; -import org.orekit.utils.Constants; -import org.orekit.utils.IERSConventions; -import org.orekit.utils.ImmutableTimeStampedCache; -import org.orekit.utils.PVCoordinates; -import org.orekit.utils.PVCoordinatesProvider; - -/** Top level Rugged class. - * @author Luc Maisonobe - */ -public class RuggedImpl implements Rugged { - - /** Reference date. */ - private AbsoluteDate referenceDate; - - /** Inertial frame. */ - private Frame frame; - - /** Reference ellipsoid. */ - private ExtendedEllipsoid ellipsoid; - - /** Converter between spacecraft and body. */ - private SpacecraftToObservedBody scToBody; - - /** Sensors. */ - private final Map<String, Sensor> sensors; - - /** DEM intersection algorithm. */ - private IntersectionAlgorithm algorithm; - - /** Simple constructor. - */ - protected RuggedImpl() { - sensors = new HashMap<String, Sensor>(); - } - - /** {@inheritDoc} */ - @Override - public void setGeneralContext(final AbsoluteDate newReferenceDate, - final AlgorithmId algorithmID, final EllipsoidId ellipsoidID, - final InertialFrameId inertialFrameID, - final BodyRotatingFrameId bodyRotatingFrameID, - final List<Pair<AbsoluteDate, PVCoordinates>> positionsVelocities, final int pvInterpolationOrder, - final List<Pair<AbsoluteDate, Rotation>> quaternions, final int aInterpolationOrder) - throws RuggedException { - try { - - // time reference - this.referenceDate = newReferenceDate; - - // 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); - - } catch (OrekitException oe) { - throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); - } - } - - /** Set up general context. - * <p> - * This method is the first one that must be called, otherwise the - * other methods will fail due to uninitialized context. - * </p> - * @param newReferenceDate reference date from which all other dates are computed - * @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 propagator global propagator - * @exception RuggedException if data needed for some frame cannot be loaded - */ - public void setGeneralContext(final AbsoluteDate newReferenceDate, - final AlgorithmId algorithmID, final EllipsoidId ellipsoidID, - final InertialFrameId inertialFrameID, - final BodyRotatingFrameId bodyRotatingFrameID, - final Propagator propagator) - throws RuggedException { - try { - - // time reference - this.referenceDate = newReferenceDate; - - // space reference - frame = selectInertialFrame(inertialFrameID); - ellipsoid = selectEllipsoid(ellipsoidID, selectBodyRotatingFrame(bodyRotatingFrameID)); - - // orbit/attitude to body converter - scToBody = new SpacecraftToObservedBody(frame, ellipsoid.getBodyFrame(), - propagator, propagator.getAttitudeProvider()); - - // intersection algorithm - algorithm = selectAlgorithm(algorithmID); - - } catch (OrekitException oe) { - throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); - } - } - - /** Get the reference date. - * @return reference date - */ - public AbsoluteDate getReferenceDate() { - return referenceDate; - } - - /** {@inheritDoc} */ - @Override - public void setUpTilesManagement(final TileUpdater updater, final int maxCachedTiles) { - algorithm.setUpTilesManagement(updater, maxCachedTiles); - } - - /** {@inheritDoc} */ - @Override - public void setLineSensor(final String sensorName, final List<PixelLOS> linesOfSigth, final LineDatation datationModel) { - final List<Vector3D> positions = new ArrayList<Vector3D>(linesOfSigth.size()); - final List<Vector3D> los = new ArrayList<Vector3D>(linesOfSigth.size()); - for (final PixelLOS plos : linesOfSigth) { - positions.add(new Vector3D(plos.getPx(), plos.getPy(), plos.getPz())); - los.add(new Vector3D(plos.getDx(), plos.getDy(), plos.getDz())); - } - final Sensor sensor = new Sensor(sensorName, referenceDate, datationModel, positions, los); - sensors.put(sensor.getName(), sensor); - } - - /** Select inertial frame. - * @param inertialFrame inertial frame identifier - * @return inertial frame - * @exception OrekitException 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); - } - - } - - /** 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 - */ - 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); - } - - } - - /** Select ellipsoid. - * @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 { - - // set up the ellipsoid - switch (ellipsoidID) { - case GRS80 : - return new ExtendedEllipsoid(6378137.0, 1.0 / 298.257222101, bodyFrame); - case WGS84 : - return new ExtendedEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, - Constants.WGS84_EARTH_FLATTENING, - bodyFrame); - case IERS96 : - return new ExtendedEllipsoid(6378136.49, 1.0 / 298.25645, bodyFrame); - case IERS2003 : - return new ExtendedEllipsoid(6378136.6, 1.0 / 298.25642, bodyFrame); - default : - // this should never happen - throw RuggedException.createInternalError(null); - } - - } - - /** Select attitude provider. - * @param quaternions satellite quaternions - * @param interpolationOrder order to use for interpolation - * @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 { - - // 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)); - } - return new TabulatedProvider(attitudes, interpolationOrder, false); - - } - - /** Select position/velocity provider. - * @param positionsVelocities satellite position and velocity - * @param interpolationOrder order to use for interpolation - * @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 { - - // 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); - orbits.add(orbit); - } - - final ImmutableTimeStampedCache<Orbit> cache = - new ImmutableTimeStampedCache<Orbit>(interpolationOrder, orbits); - return new PVCoordinatesProvider() { - - /** {@inhritDoc} */ - @Override - public PVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame f) - throws OrekitException { - final List<Orbit> sample = cache.getNeighbors(date); - final Orbit interpolated = sample.get(0).interpolate(date, sample); - return interpolated.getPVCoordinates(date, f); - } - - }; - - } - - /** Select DEM intersection algorithm. - * @param algorithmID intersection algorithm identifier - * @return selected algorithm - */ - private IntersectionAlgorithm selectAlgorithm(final AlgorithmId algorithmID) { - - // set up the algorithm - switch (algorithmID) { - case DUVENHAGE : - return new DuvenhageAlgorithm(); - case BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY : - return new BasicScanAlgorithm(); - case IGNORE_DEM_USE_ELLIPSOID : - return new IgnoreDEMAlgorithm(); - default : - // this should never happen - throw RuggedException.createInternalError(null); - } - - } - - /** {@inheritDoc} */ - @Override - public GeodeticPoint[] directLocalization(final String sensorName, final double lineNumber) - throws RuggedException { - try { - - checkContext(); - - // select the sensor - final Sensor sensor = getSensor(sensorName); - - // 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 GeodeticPoint[] gp = new GeodeticPoint[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)); - - gp[i] = algorithm.intersection(ellipsoid, - fixed.transformPosition(sensor.getPosition(i)), - fixed.transformVector(sensor.getLos(i))); - } - - return gp; - - } catch (OrekitException oe) { - throw new RuggedException(oe, oe.getSpecifier(), oe.getParts()); - } - } - - /** {@inheritDoc} */ - @Override - public SensorPixel inverseLocalization(final String sensorName, final GeodeticPoint groundPoint) - throws RuggedException { - - checkContext(); - final Sensor sensor = getSensor(sensorName); - - // TODO: implement direct localization - throw RuggedException.createInternalError(null); - - } - - /** Check if context has been initialized. - * @exception RuggedException if context has not been initialized - */ - private void checkContext() throws RuggedException { - if (frame == null) { - throw new RuggedException(RuggedMessages.UNINITIALIZED_CONTEXT); - } - } - - /** Get a sensor. - * @param sensorName sensor name - * @return selected sensor - * @exception RuggedException if sensor is not known - */ - private Sensor getSensor(final String sensorName) throws RuggedException { - final Sensor sensor = sensors.get(sensorName); - if (sensor == null) { - throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName); - } - return sensor; - } - -} diff --git a/src/main/java/org/orekit/rugged/core/Sensor.java b/src/main/java/org/orekit/rugged/core/Sensor.java index 9758afc8a3ee95dd598fd8b8fb35556a409905b3..e1364c1570a8da3737a1c59f74de85d03a0532fc 100644 --- a/src/main/java/org/orekit/rugged/core/Sensor.java +++ b/src/main/java/org/orekit/rugged/core/Sensor.java @@ -28,7 +28,7 @@ import org.orekit.time.AbsoluteDate; * </p> * @author Luc Maisonobe */ -class Sensor { +public class Sensor { /** Name of the sensor. */ private final String name; diff --git a/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java b/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java index 044471c8152c587ad7c39bb77ff6f2a0e5fdef0c..43e46016639c99d6a58c0dcda00fe19caecb9d11 100644 --- a/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java +++ b/src/main/java/org/orekit/rugged/core/SpacecraftToObservedBody.java @@ -28,7 +28,7 @@ import org.orekit.utils.PVCoordinatesProvider; /** Provider for observation transforms. * @author Luc Maisonobe */ -class SpacecraftToObservedBody { +public class SpacecraftToObservedBody { /** Inertial frame. */ private Frame inertialFrame; @@ -48,9 +48,9 @@ class SpacecraftToObservedBody { * @param pvProvider orbit propagator/interpolator * @param aProvider attitude propagator/interpolator */ - protected SpacecraftToObservedBody(final Frame inertialFrame, final Frame bodyFrame, - final PVCoordinatesProvider pvProvider, - final AttitudeProvider aProvider) { + public SpacecraftToObservedBody(final Frame inertialFrame, final Frame bodyFrame, + final PVCoordinatesProvider pvProvider, + final AttitudeProvider aProvider) { this.inertialFrame = inertialFrame; this.bodyFrame = bodyFrame; this.pvProvider = pvProvider; diff --git a/src/test/java/org/orekit/rugged/core/RuggedImplTest.java b/src/test/java/org/orekit/rugged/api/RuggedTest.java similarity index 99% rename from src/test/java/org/orekit/rugged/core/RuggedImplTest.java rename to src/test/java/org/orekit/rugged/api/RuggedTest.java index 33cfa2f2d33d1bbfafbe17539bc2479da9818aab..3132e1cb5b7b89263ba2d2c8b1d90df09579c7fa 100644 --- a/src/test/java/org/orekit/rugged/core/RuggedImplTest.java +++ b/src/test/java/org/orekit/rugged/api/RuggedTest.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.orekit.rugged.core; +package org.orekit.rugged.api; import java.io.File; @@ -77,7 +77,7 @@ import org.orekit.utils.Constants; import org.orekit.utils.IERSConventions; import org.orekit.utils.PVCoordinates; -public class RuggedImplTest { +public class RuggedTest { @Rule public TemporaryFolder tempFolder = new TemporaryFolder(); @@ -138,7 +138,7 @@ public class RuggedImplTest { createQ(t0,19.000, 0.522119033749, -0.395304129256, 0.577847874330, 0.487050504694), createQ(t0,20.000, 0.522421006719, -0.395049578765, 0.577574493570, 0.487257453954)); - RuggedImpl rugged = new RuggedImpl(); + Rugged rugged = new Rugged(); rugged.setGeneralContext(t0, AlgorithmId.DUVENHAGE, EllipsoidId.WGS84, @@ -162,7 +162,7 @@ public class RuggedImplTest { Orbit orbit = createOrbit(gravityField); Propagator propagator = createPropagator(earth, gravityField, orbit); - RuggedImpl rugged = new RuggedImpl(); + Rugged rugged = new Rugged(); rugged.setGeneralContext(propagator.getInitialState().getDate(), AlgorithmId.DUVENHAGE, EllipsoidId.WGS84, @@ -213,7 +213,7 @@ public class RuggedImplTest { propagator.propagate(crossing.shiftedBy(lineDatation.getDate(lastLine) + 1.0)); Propagator ephemeris = propagator.getGeneratedEphemeris(); - RuggedImpl rugged = new RuggedImpl(); + Rugged rugged = new Rugged(); rugged.setGeneralContext(crossing, AlgorithmId.DUVENHAGE, EllipsoidId.WGS84,