From 1ff9e6a84e0fe12f84a70ab72dcc5eb48bd16c30 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Sun, 9 Mar 2014 17:26:17 +0100 Subject: [PATCH] Boilerplate part for Rugged interface implementation. --- .../orekit/rugged/core/AbstractRugged.java | 309 ++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 rugged-core/src/main/java/org/orekit/rugged/core/AbstractRugged.java diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/AbstractRugged.java b/rugged-core/src/main/java/org/orekit/rugged/core/AbstractRugged.java new file mode 100644 index 00000000..15e9ce68 --- /dev/null +++ b/rugged-core/src/main/java/org/orekit/rugged/core/AbstractRugged.java @@ -0,0 +1,309 @@ +/* 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.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.math3.geometry.euclidean.threed.Rotation; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.attitudes.Attitude; +import org.orekit.attitudes.AttitudeProvider; +import org.orekit.attitudes.TabulatedProvider; +import org.orekit.bodies.BodyShape; +import org.orekit.bodies.OneAxisEllipsoid; +import org.orekit.data.DataProvidersManager; +import org.orekit.data.DirectoryCrawler; +import org.orekit.errors.OrekitException; +import org.orekit.frames.Frame; +import org.orekit.frames.FramesFactory; +import org.orekit.orbits.CartesianOrbit; +import org.orekit.orbits.Orbit; +import org.orekit.propagation.Propagator; +import org.orekit.rugged.api.GroundPoint; +import org.orekit.rugged.api.Rugged; +import org.orekit.rugged.api.RuggedException; +import org.orekit.rugged.api.RuggedMessages; +import org.orekit.rugged.api.SatellitePV; +import org.orekit.rugged.api.SatelliteQ; +import org.orekit.rugged.api.SensorPixel; +import org.orekit.rugged.api.Rugged.BodyRotatingFrame; +import org.orekit.rugged.api.Rugged.Ellipsoid; +import org.orekit.rugged.api.Rugged.InertialFrame; +import org.orekit.time.AbsoluteDate; +import org.orekit.time.TimeScale; +import org.orekit.time.TimeScalesFactory; +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; + +/** Boilerplate part for direct and inverse localization. + * @author Luc Maisonobe + */ +public abstract class AbstractRugged implements Rugged { + + /** UTC time scale. */ + private TimeScale utc; + + /** Inertial frame. */ + private Frame frame; + + /** Reference ellipsoid. */ + private BodyShape shape; + + /** Orbit propagator/interpolator. */ + private PVCoordinatesProvider pvProvider; + + /** Attitude propagator/interpolator. */ + private AttitudeProvider aProvider; + + /** Simple constructor. + */ + protected AbstractRugged() { + } + + /** {@inheritDoc} */ + @Override + public void setGeneralContext(final File orekitDataDir, + final Ellipsoid ellipsoid, + final InertialFrame inertialFrame, + final BodyRotatingFrame bodyRotatingFrame, + final List<SatellitePV> positionsVelocities, final int pvInterpolationOrder, + final List<SatelliteQ> quaternions, final int aInterpolationOrder) + throws RuggedException { + try { + utc = selectTimeScale(orekitDataDir); + frame = selectInertialFrame(inertialFrame); + shape = selectEllipsoid(ellipsoid, selectBodyRotatingFrame(bodyRotatingFrame)); + pvProvider = selectPVCoordinatesProvider(positionsVelocities, pvInterpolationOrder); + aProvider = selectAttitudeProvider(quaternions, aInterpolationOrder); + } 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 orekitDataDir top directory for Orekit data + * @param ellipsoid reference ellipsoid + * @param inertialFrameName inertial frame + * @param bodyRotatingFrame body rotating frame + * @param propagator global propagator + * @exception RuggedException if data needed for some frame cannot be loaded + */ + public void setGeneralContext(final File orekitDataDir, final Ellipsoid ellipsoid, + final InertialFrame inertialFrame, + final BodyRotatingFrame bodyRotatingFrame, + final Propagator propagator) + throws RuggedException { + try { + utc = selectTimeScale(orekitDataDir); + frame = selectInertialFrame(inertialFrame); + shape = selectEllipsoid(ellipsoid, selectBodyRotatingFrame(bodyRotatingFrame)); + pvProvider = propagator; + aProvider = propagator.getAttitudeProvider(); + } catch (OrekitException oe) { + throw new RuggedException(oe, oe.getSpecifier(), oe.getParts().clone()); + } + } + + /** Select time scale Orekit data. + * @param orekitDataDir top directory for Orekit data + * @return utc time scale + * @exception OrekitException if data needed for some frame cannot be loaded + */ + private TimeScale selectTimeScale(final File orekitDataDir) + throws OrekitException { + + // set up Orekit data + DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(orekitDataDir)); + return TimeScalesFactory.getUTC(); + + } + + /** Select inertial frame. + * @param inertialFrameName inertial frame + * @return inertial frame + * @exception OrekitException if data needed for some frame cannot be loaded + */ + private Frame selectInertialFrame(final InertialFrame 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 + * @return body rotating frame + * @exception OrekitException if data needed for some frame cannot be loaded + */ + private Frame selectBodyRotatingFrame(final BodyRotatingFrame bodyRotatingFrame) + throws OrekitException { + + // set up the rotating frame + switch (bodyRotatingFrame) { + case ITRF : + return FramesFactory.getITRF(IERSConventions.IERS_2010, true); + case GTOD : + return FramesFactory.getGTOD(IERSConventions.IERS_1996, true); + default : + // this should never happen + throw RuggedException.createInternalError(null); + } + + } + + /** Select ellipsoid. + * @param ellipsoid reference ellipsoid + * @param bodyFrame body rotating frame + * @exception OrekitException if data needed for some frame cannot be loaded + */ + private BodyShape selectEllipsoid(final Ellipsoid ellipsoid, final Frame bodyFrame) + throws OrekitException { + + // set up the ellipsoid + switch (ellipsoid) { + case GRS80 : + return new OneAxisEllipsoid(6378137.0, 1.0 / 298.257222101, bodyFrame); + case WGS84 : + return new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, + Constants.WGS84_EARTH_FLATTENING, + bodyFrame); + case IERS96 : + return new OneAxisEllipsoid(6378136.49, 1.0 / 298.25645, bodyFrame); + case IERS2003 : + return new OneAxisEllipsoid(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 + * @exception OrekitException if data needed for some frame cannot be loaded + */ + private AttitudeProvider selectAttitudeProvider(final List<SatelliteQ> quaternions, + final int interpolationOrder) + throws OrekitException { + + // set up the attitude provider + final List<Attitude> attitudes = new ArrayList<Attitude>(quaternions.size()); + for (final SatelliteQ sq : quaternions) { + final AbsoluteDate date = new AbsoluteDate(sq.getDate(), utc); + final Rotation rotation = new Rotation(sq.getQ0(), sq.getQ1(), sq.getQ2(), sq.getQ3(), true); + attitudes.add(new Attitude(date, frame, rotation, 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 + * @exception OrekitException if data needed for some frame cannot be loaded + */ + private PVCoordinatesProvider selectPVCoordinatesProvider(final List<SatellitePV> positionsVelocities, + final int interpolationOrder) + throws OrekitException { + + // set up the ephemeris + final List<Orbit> orbits = new ArrayList<Orbit>(positionsVelocities.size()); + for (final SatellitePV pv : positionsVelocities) { + final AbsoluteDate date = new AbsoluteDate(pv.getDate(), utc); + final Vector3D position = new Vector3D(pv.getPx(), pv.getPy(), pv.getPz()); + final Vector3D velocity = new Vector3D(pv.getVx(), pv.getVy(), pv.getVz()); + final CartesianOrbit orbit = new CartesianOrbit(new PVCoordinates(position, velocity), + frame, date, 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 frame) + throws OrekitException { + final List<Orbit> sample = cache.getNeighbors(date); + final Orbit interpolated = sample.get(0).interpolate(date, sample); + return interpolated.getPVCoordinates(date, frame); + } + + }; + + } + + /** {@inheritDoc} */ + @Override + public GroundPoint[] directLocalization(String sensorName, int lineNumber) + throws RuggedException { + + checkContext(); + + // TODO: implement direct localization + throw RuggedException.createInternalError(null); + + } + + /** {@inheritDoc} */ + @Override + public SensorPixel inverseLocalization(String sensorName, GroundPoint groundPoint) + throws RuggedException { + + checkContext(); + + // 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); + } + } + +} -- GitLab