Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • orekit/rugged
  • sdinot/rugged
  • yzokras/rugged
  • youngcle/rugged-mod
4 results
Show changes
Showing
with 5235 additions and 156 deletions
package org.orekit.rugged.adjustment.util;
import org.orekit.rugged.api.Rugged;
import org.orekit.utils.ParameterDriver;
/** Apply disruptions or select/unselect parameter to adjust for Refining JUnit tests.
* @author Guylaine Prat
*/
public class RefiningParametersDriver {
// Part of the name of parameter drivers
static final String rollSuffix = "_roll";
static final String pitchSuffix = "_pitch";
static final String factorName = "factor";
/** Apply disruptions on acquisition for roll angle
* @param rugged Rugged instance
* @param sensorName line sensor name
* @param rollValue rotation on roll value
*/
public static void applyDisruptionsRoll(final Rugged rugged, final String sensorName, final double rollValue) {
rugged.
getLineSensor(sensorName).
getParametersDrivers().
filter(driver -> driver.getName().equals(sensorName + rollSuffix)).
findFirst().get().setValue(rollValue);
}
/** Apply disruptions on acquisition for pitch angle
* @param rugged Rugged instance
* @param sensorName line sensor name
* @param pitchValue rotation on pitch value
*/
public static void applyDisruptionsPitch(final Rugged rugged, final String sensorName, final double pitchValue) {
rugged.
getLineSensor(sensorName).
getParametersDrivers().
filter(driver -> driver.getName().equals(sensorName + pitchSuffix)).
findFirst().get().setValue(pitchValue);
}
/** Apply disruptions on acquisition for scale factor
* @param rugged Rugged instance
* @param sensorName line sensor name
* @param factorValue scale factor
*/
public static void applyDisruptionsFactor(final Rugged rugged, final String sensorName, final double factorValue) {
rugged.
getLineSensor(sensorName).
getParametersDrivers().
filter(driver -> driver.getName().equals(factorName)).
findFirst().get().setValue(factorValue);
}
/** Select roll angle to adjust
* @param rugged Rugged instance
* @param sensorName line sensor name
*/
public static void setSelectedRoll(final Rugged rugged, final String sensorName) {
ParameterDriver rollDriver =
rugged.getLineSensor(sensorName).getParametersDrivers().
filter(driver -> driver.getName().equals(sensorName + rollSuffix)).findFirst().get();
rollDriver.setSelected(true);
}
/** Select pitch angle to adjust
* @param rugged Rugged instance
* @param sensorName line sensor name
*/
public static void setSelectedPitch(final Rugged rugged, final String sensorName) {
ParameterDriver pitchDriver =
rugged.getLineSensor(sensorName).getParametersDrivers().
filter(driver -> driver.getName().equals(sensorName + pitchSuffix)).findFirst().get();
pitchDriver.setSelected(true);
}
/** Select scale factor to adjust
* @param rugged Rugged instance
* @param sensorName line sensor name
*/
public static void setSelectedFactor(final Rugged rugged, final String sensorName) {
ParameterDriver factorDriver =
rugged.getLineSensor(sensorName).getParametersDrivers().
filter(driver -> driver.getName().equals(factorName)).findFirst().get();
factorDriver.setSelected(true);
}
/** Unselect roll angle to adjust (for test coverage purpose)
* @param rugged Rugged instance
* @param sensorName line sensor name
*/
public static void unselectRoll(final Rugged rugged, final String sensorName) {
ParameterDriver rollDriver =
rugged.getLineSensor(sensorName).getParametersDrivers().
filter(driver -> driver.getName().equals(sensorName + rollSuffix)).findFirst().get();
rollDriver.setSelected(false);
}
/** Unselect pitch angle to adjust (for test coverage purpose)
* @param rugged Rugged instance
* @param sensorName line sensor name
*/
public static void unselectPitch(final Rugged rugged, final String sensorName) {
ParameterDriver pitchDriver =
rugged.getLineSensor(sensorName).getParametersDrivers().
filter(driver -> driver.getName().equals(sensorName + pitchSuffix)).findFirst().get();
pitchDriver.setSelected(false);
}
/** Unselect factor angle to adjust (for test coverage purpose)
* @param rugged Rugged instance
* @param sensorName line sensor name
*/
public static void unselectFactor(final Rugged rugged, final String sensorName) {
ParameterDriver factorDriver =
rugged.getLineSensor(sensorName).getParametersDrivers().
filter(driver -> driver.getName().equals(factorName)).findFirst().get();
factorDriver.setSelected(false);
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.api;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.RotationConvention;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.orekit.attitudes.AttitudeProvider;
import org.orekit.attitudes.NadirPointing;
import org.orekit.attitudes.YawCompensation;
import org.orekit.bodies.BodyShape;
import org.orekit.bodies.CelestialBodyFactory;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
import org.orekit.forces.gravity.ThirdBodyAttraction;
import org.orekit.forces.gravity.potential.GravityFieldFactory;
import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.frames.Transform;
import org.orekit.orbits.CircularOrbit;
import org.orekit.orbits.Orbit;
import org.orekit.orbits.OrbitType;
import org.orekit.orbits.PositionAngle;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.analytical.KeplerianPropagator;
import org.orekit.propagation.numerical.NumericalPropagator;
import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.errors.RuggedMessages;
import org.orekit.rugged.linesensor.LineDatation;
import org.orekit.rugged.linesensor.LineSensor;
import org.orekit.rugged.linesensor.LinearLineDatation;
import org.orekit.rugged.los.LOSBuilder;
import org.orekit.rugged.los.TimeDependentLOS;
import org.orekit.rugged.raster.RandomLandscapeUpdater;
import org.orekit.rugged.raster.TileUpdater;
import org.orekit.rugged.raster.VolcanicConeElevationUpdater;
import org.orekit.rugged.refraction.AtmosphericRefraction;
import org.orekit.rugged.refraction.ConstantRefractionLayer;
import org.orekit.rugged.refraction.MultiLayerModel;
import org.orekit.rugged.utils.ExtendedEllipsoid;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.AngularDerivativesFilter;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.TimeStampedAngularCoordinates;
import org.orekit.utils.TimeStampedPVCoordinates;
public class RuggedBuilderTest {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testSetContextWithEphemerides()
throws URISyntaxException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
AbsoluteDate t0 = new AbsoluteDate("2012-01-01T00:00:00", TimeScalesFactory.getUTC());
List<TimeStampedPVCoordinates> pv = Arrays.asList(
createPV(t0, 0.000, -1545168.478, -7001985.361, 0.000, -1095.152224, 231.344922, -7372.851944),
createPV(t0, 1.000, -1546262.794, -7001750.226, -7372.851, -1093.478904, 238.925123, -7372.847995),
createPV(t0, 2.000, -1547355.435, -7001507.511, -14745.693, -1091.804408, 246.505033, -7372.836044),
createPV(t0, 3.000, -1548446.402, -7001257.216, -22118.520, -1090.128736, 254.084644, -7372.816090),
createPV(t0, 4.000, -1549535.693, -7000999.342, -29491.323, -1088.451892, 261.663949, -7372.788133),
createPV(t0, 5.000, -1550623.306, -7000733.888, -36864.094, -1086.773876, 269.242938, -7372.752175),
createPV(t0, 6.000, -1551709.240, -7000460.856, -44236.825, -1085.094690, 276.821604, -7372.708214),
createPV(t0, 7.000, -1552793.495, -7000180.245, -51609.507, -1083.414336, 284.399938, -7372.656251),
createPV(t0, 8.000, -1553876.068, -6999892.056, -58982.134, -1081.732817, 291.977932, -7372.596287),
createPV(t0, 9.000, -1554956.960, -6999596.289, -66354.697, -1080.050134, 299.555578, -7372.528320),
createPV(t0,10.000, -1556036.168, -6999292.945, -73727.188, -1078.366288, 307.132868, -7372.452352),
createPV(t0,11.000, -1557113.692, -6998982.024, -81099.599, -1076.681282, 314.709792, -7372.368382),
createPV(t0,12.000, -1558189.530, -6998663.526, -88471.922, -1074.995118, 322.286344, -7372.276411),
createPV(t0,13.000, -1559263.682, -6998337.451, -95844.150, -1073.307797, 329.862513, -7372.176439),
createPV(t0,14.000, -1560336.145, -6998003.801, -103216.273, -1071.619321, 337.438294, -7372.068466),
createPV(t0,15.000, -1561406.920, -6997662.575, -110588.284, -1069.929692, 345.013676, -7371.952492),
createPV(t0,16.000, -1562476.004, -6997313.774, -117960.175, -1068.238912, 352.588652, -7371.828517),
createPV(t0,17.000, -1563543.398, -6996957.398, -125331.938, -1066.546983, 360.163213, -7371.696542),
createPV(t0,18.000, -1564609.098, -6996593.447, -132703.565, -1064.853906, 367.737352, -7371.556566),
createPV(t0,19.000, -1565673.105, -6996221.923, -140075.049, -1063.159684, 375.311060, -7371.408591),
createPV(t0,20.000, -1566735.417, -6995842.825, -147446.380, -1061.464319, 382.884328, -7371.252616));
List<TimeStampedAngularCoordinates> q = Arrays.asList(
createQ(t0, 0.000, 0.516354347549, -0.400120145429, 0.583012133139, 0.483093065155),
createQ(t0, 1.000, 0.516659035405, -0.399867643627, 0.582741754688, 0.483302551263),
createQ(t0, 2.000, 0.516963581177, -0.399615033309, 0.582471217473, 0.483511904409),
createQ(t0, 3.000, 0.517267984776, -0.399362314553, 0.582200521577, 0.483721124530),
createQ(t0, 4.000, 0.517572246112, -0.399109487434, 0.581929667081, 0.483930211565),
createQ(t0, 5.000, 0.517876365096, -0.398856552030, 0.581658654071, 0.484139165451),
createQ(t0, 6.000, 0.518180341637, -0.398603508416, 0.581387482627, 0.484347986126),
createQ(t0, 7.000, 0.518484175647, -0.398350356669, 0.581116152834, 0.484556673529),
createQ(t0, 8.000, 0.518787867035, -0.398097096866, 0.580844664773, 0.484765227599),
createQ(t0, 9.000, 0.519091415713, -0.397843729083, 0.580573018530, 0.484973648272),
createQ(t0,10.000, 0.519394821590, -0.397590253397, 0.580301214186, 0.485181935488),
createQ(t0,11.000, 0.519698084578, -0.397336669885, 0.580029251825, 0.485390089185),
createQ(t0,12.000, 0.520001204587, -0.397082978623, 0.579757131530, 0.485598109301),
createQ(t0,13.000, 0.520304181527, -0.396829179688, 0.579484853385, 0.485805995775),
createQ(t0,14.000, 0.520607015311, -0.396575273158, 0.579212417473, 0.486013748545),
createQ(t0,15.000, 0.520909705847, -0.396321259108, 0.578939823877, 0.486221367550),
createQ(t0,16.000, 0.521212253049, -0.396067137616, 0.578667072681, 0.486428852729),
createQ(t0,17.000, 0.521514656825, -0.395812908759, 0.578394163969, 0.486636204020),
createQ(t0,18.000, 0.521816917089, -0.395558572613, 0.578121097824, 0.486843421362),
createQ(t0,19.000, 0.522119033749, -0.395304129256, 0.577847874330, 0.487050504694),
createQ(t0,20.000, 0.522421006719, -0.395049578765, 0.577574493570, 0.487257453954));
TileUpdater updater =
new VolcanicConeElevationUpdater(new GeodeticPoint(FastMath.toRadians(13.25667),
FastMath.toRadians(123.685),
2463.0),
FastMath.toRadians(30.0), 16.0,
FastMath.toRadians(1.0), 1201);
RuggedBuilder builder = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setTimeSpan(pv.get(0).getDate(), pv.get(pv.size() - 1).getDate(), 0.001, 5.0);
try {
builder.build();
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
Assert.assertEquals("RuggedBuilder.setEllipsoid()", re.getParts()[0]);
}
builder.setEllipsoid(EllipsoidId.GRS80, BodyRotatingFrameId.ITRF);
try {
builder.build();
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
Assert.assertEquals("RuggedBuilder.setTrajectory()", re.getParts()[0]);
}
builder.setTrajectory(InertialFrameId.EME2000,
pv, 8, CartesianDerivativesFilter.USE_PV,
q, 8, AngularDerivativesFilter.USE_R);
Assert.assertSame(FramesFactory.getEME2000(), builder.getInertialFrame());
// light time correction and aberration of light correction are enabled by default
Rugged rugged = builder.build();
Assert.assertTrue(rugged.isLightTimeCorrected());
Assert.assertTrue(rugged.isAberrationOfLightCorrected());
Assert.assertTrue(builder.getLightTimeCorrection());
Assert.assertTrue(builder.getAberrationOfLightCorrection());
builder.setLightTimeCorrection(false);
rugged = builder.build();
Assert.assertFalse(rugged.isLightTimeCorrected());
Assert.assertTrue(rugged.isAberrationOfLightCorrected());
Assert.assertFalse(builder.getLightTimeCorrection());
Assert.assertTrue(builder.getAberrationOfLightCorrection());
builder.setAberrationOfLightCorrection(false);
rugged = builder.build();
Assert.assertFalse(rugged.isLightTimeCorrected());
Assert.assertFalse(rugged.isAberrationOfLightCorrected());
Assert.assertFalse(builder.getLightTimeCorrection());
Assert.assertFalse(builder.getAberrationOfLightCorrection());
AtmosphericRefraction atmosphericRefraction = new MultiLayerModel(builder.getEllipsoid());
builder.setRefractionCorrection(atmosphericRefraction);
rugged = builder.build();
MultiLayerModel atmosphericRefractionFromBuilder = (MultiLayerModel) builder.getRefractionCorrection();
Field atmos = atmosphericRefractionFromBuilder.getClass().getDeclaredField("ellipsoid");
atmos.setAccessible(true);
ExtendedEllipsoid ellipsoidAtmos = (ExtendedEllipsoid) atmos.get(atmosphericRefractionFromBuilder);
Assert.assertEquals(builder.getEllipsoid().getEquatorialRadius(), ellipsoidAtmos.getEquatorialRadius(), 1.0e-9);
Assert.assertEquals(builder.getEllipsoid().getFlattening(), ellipsoidAtmos.getFlattening(), 1.0e-10);
Field layers = atmosphericRefractionFromBuilder.getClass().getDeclaredField("refractionLayers");
layers.setAccessible(true);
@SuppressWarnings("unchecked")
List<ConstantRefractionLayer> layersAtmos = (List<ConstantRefractionLayer>) layers.get(atmosphericRefractionFromBuilder);
Field layersExpected = atmosphericRefraction.getClass().getDeclaredField("refractionLayers");
layersExpected.setAccessible(true);
@SuppressWarnings("unchecked")
List<ConstantRefractionLayer> layersAtmosExpected = (List<ConstantRefractionLayer>) layersExpected.get(atmosphericRefraction);
Assert.assertEquals(layersAtmosExpected.size(), layersAtmos.size());
List<ConstantRefractionLayer> copyAtmosExpected = new ArrayList<ConstantRefractionLayer>(layersAtmosExpected);
List<ConstantRefractionLayer> copyAtmos = new ArrayList<ConstantRefractionLayer>(layersAtmos);
Assert.assertTrue(copyAtmosExpected.removeAll(layersAtmos) && copyAtmos.removeAll(layersAtmosExpected));
Assert.assertTrue(copyAtmosExpected.isEmpty() && copyAtmos.isEmpty());
Assert.assertEquals(AlgorithmId.DUVENHAGE, builder.getAlgorithm());
Assert.assertEquals(6378137.0, builder.getEllipsoid().getEquatorialRadius(), 1.0e-9);
Assert.assertEquals(1.0 / 298.257222101, builder.getEllipsoid().getFlattening(), 1.0e-10);
Assert.assertSame(updater, builder.getTileUpdater());
Assert.assertEquals(8, builder.getMaxCachedTiles());
Assert.assertTrue(Double.isNaN(builder.getConstantElevation()));
Assert.assertEquals(pv.get(0).getDate(), builder.getMinDate());
Assert.assertEquals(pv.get(pv.size() - 1).getDate(), builder.getMaxDate());
Assert.assertEquals(0.001, builder.getTStep(), 1.0e-10);
Assert.assertEquals(5.0, builder.getOvershootTolerance(), 1.0e-10);
Assert.assertSame(FramesFactory.getEME2000(), builder.getInertialFrame());
Assert.assertSame(pv, builder.getPositionsVelocities());
Assert.assertEquals(8, builder.getPVInterpolationNumber());
Assert.assertEquals(CartesianDerivativesFilter.USE_PV, builder.getPVFilter());
Assert.assertSame(q, builder.getQuaternions());
Assert.assertEquals(8, builder.getAInterpolationNumber());
Assert.assertEquals(AngularDerivativesFilter.USE_R, builder.getAFilter());
Assert.assertTrue(builder.getLineSensors().isEmpty());
LineSensor lineSensor = new LineSensor("line", new LinearLineDatation(t0, 2000 / 2, 1.0 / 1.5e-3),
Vector3D.ZERO,
createLOSPerfectLine(Vector3D.PLUS_K,
Vector3D.PLUS_I, FastMath.toRadians(1.0), 2000));
builder.addLineSensor(lineSensor);
Assert.assertEquals(1, builder.getLineSensors().size());
Assert.assertSame(lineSensor, builder.getLineSensors().get(0));
builder.clearLineSensors();
Assert.assertTrue(builder.getLineSensors().isEmpty());
builder.setTrajectory(InertialFrameId.GCRF,
pv, 8, CartesianDerivativesFilter.USE_PV,
q, 8, AngularDerivativesFilter.USE_R);
Assert.assertSame(FramesFactory.getGCRF(), builder.getInertialFrame());
builder.setTrajectory(InertialFrameId.MOD,
pv, 8, CartesianDerivativesFilter.USE_PV,
q, 8, AngularDerivativesFilter.USE_R);
Assert.assertSame(FramesFactory.getMOD(IERSConventions.IERS_1996), builder.getInertialFrame());
builder.setTrajectory(InertialFrameId.TOD,
pv, 8, CartesianDerivativesFilter.USE_PV,
q, 8, AngularDerivativesFilter.USE_R);
Assert.assertSame(FramesFactory.getTOD(IERSConventions.IERS_1996, true), builder.getInertialFrame());
builder.setTrajectory(InertialFrameId.VEIS1950,
pv, 8, CartesianDerivativesFilter.USE_PV,
q, 8, AngularDerivativesFilter.USE_R);
Assert.assertSame(FramesFactory.getVeis1950(), builder.getInertialFrame());
builder.setAlgorithm(null);
try {
builder.build();
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
Assert.assertEquals("RuggedBuilder.setAlgorithmID()", re.getParts()[0]);
}
builder.setAlgorithm(AlgorithmId.CONSTANT_ELEVATION_OVER_ELLIPSOID);
builder.setConstantElevation(Double.NaN);
try {
builder.build();
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
Assert.assertEquals("RuggedBuilder.setConstantElevation()", re.getParts()[0]);
}
builder.setConstantElevation(100.0);
Assert.assertNotNull(builder.build());
builder.setAlgorithm(AlgorithmId.BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY);
builder.setDigitalElevationModel(null, 8);
try {
builder.build();
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
Assert.assertEquals("RuggedBuilder.setDigitalElevationModel()", re.getParts()[0]);
}
builder.setDigitalElevationModel(updater, 8);
Assert.assertNotNull(builder.build());
}
@Test
public void testSetContextWithPropagator()
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
BodyShape earth = createEarth();
NormalizedSphericalHarmonicsProvider gravityField = createGravityField();
Orbit orbit = createOrbit(gravityField.getMu());
Propagator propagator = createPropagator(earth, gravityField, orbit);
TileUpdater updater =
new VolcanicConeElevationUpdater(new GeodeticPoint(FastMath.toRadians(13.25667),
FastMath.toRadians(123.685),
2463.0),
FastMath.toRadians(30.0), 16.0,
FastMath.toRadians(1.0), 1201);
RuggedBuilder builder = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.IERS96, BodyRotatingFrameId.ITRF).
setTimeSpan(orbit.getDate().shiftedBy(-10.0), orbit.getDate().shiftedBy(+10.0), 0.001, 5.0).
setTrajectory(1.0, 8, CartesianDerivativesFilter.USE_PV, AngularDerivativesFilter.USE_R, propagator);
// light time correction and aberration of light correction are enabled by default
Rugged rugged = builder.build();
Assert.assertTrue(rugged.isLightTimeCorrected());
Assert.assertTrue(rugged.isAberrationOfLightCorrected());
builder.setLightTimeCorrection(false);
rugged = builder.build();
Assert.assertFalse(rugged.isLightTimeCorrected());
Assert.assertTrue(rugged.isAberrationOfLightCorrected());
builder.setAberrationOfLightCorrection(false);
rugged = builder.build();
Assert.assertFalse(rugged.isLightTimeCorrected());
Assert.assertFalse(rugged.isAberrationOfLightCorrected());
Assert.assertEquals(orbit.getDate().shiftedBy(-10.0), rugged.getMinDate());
Assert.assertEquals(orbit.getDate().shiftedBy(+10.0), rugged.getMaxDate());
Assert.assertEquals(0, rugged.getLineSensors().size());
}
@Test
public void testOutOfTimeRange()
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
AbsoluteDate t0 = new AbsoluteDate("2012-01-01T00:00:00", TimeScalesFactory.getUTC());
List<TimeStampedPVCoordinates> pv = Arrays.asList(
createPV(t0, 0.000, -1545168.478, -7001985.361, 0.000, -1095.152224, 231.344922, -7372.851944),
createPV(t0, 1.000, -1546262.794, -7001750.226, -7372.851, -1093.478904, 238.925123, -7372.847995),
createPV(t0, 2.000, -1547355.435, -7001507.511, -14745.693, -1091.804408, 246.505033, -7372.836044),
createPV(t0, 3.000, -1548446.402, -7001257.216, -22118.520, -1090.128736, 254.084644, -7372.816090),
createPV(t0, 4.000, -1549535.693, -7000999.342, -29491.323, -1088.451892, 261.663949, -7372.788133),
createPV(t0, 5.000, -1550623.306, -7000733.888, -36864.094, -1086.773876, 269.242938, -7372.752175),
createPV(t0, 6.000, -1551709.240, -7000460.856, -44236.825, -1085.094690, 276.821604, -7372.708214),
createPV(t0, 7.000, -1552793.495, -7000180.245, -51609.507, -1083.414336, 284.399938, -7372.656251),
createPV(t0, 8.000, -1553876.068, -6999892.056, -58982.134, -1081.732817, 291.977932, -7372.596287),
createPV(t0, 9.000, -1554956.960, -6999596.289, -66354.697, -1080.050134, 299.555578, -7372.528320),
createPV(t0,10.000, -1556036.168, -6999292.945, -73727.188, -1078.366288, 307.132868, -7372.452352));
List<TimeStampedAngularCoordinates> q = Arrays.asList(
createQ(t0, 4.000, 0.517572246112, -0.399109487434, 0.581929667081, 0.483930211565),
createQ(t0, 5.000, 0.517876365096, -0.398856552030, 0.581658654071, 0.484139165451),
createQ(t0, 6.000, 0.518180341637, -0.398603508416, 0.581387482627, 0.484347986126),
createQ(t0, 7.000, 0.518484175647, -0.398350356669, 0.581116152834, 0.484556673529),
createQ(t0, 8.000, 0.518787867035, -0.398097096866, 0.580844664773, 0.484765227599));
TileUpdater updater =
new VolcanicConeElevationUpdater(new GeodeticPoint(FastMath.toRadians(13.25667),
FastMath.toRadians(123.685),
2463.0),
FastMath.toRadians(30.0), 16.0,
FastMath.toRadians(1.0), 1201);
Assert.assertNotNull(new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(t0.shiftedBy(4), t0.shiftedBy(6), 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
pv,2, CartesianDerivativesFilter.USE_PV,
q, 2, AngularDerivativesFilter.USE_R).
build());
try {
new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(t0.shiftedBy(-1), t0.shiftedBy(6), 0.001, 0.0001).
setTrajectory(InertialFrameId.EME2000,
pv, 2, CartesianDerivativesFilter.USE_PV,
q, 2, AngularDerivativesFilter.USE_R);
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
Assert.assertEquals(t0.shiftedBy(-1), re.getParts()[0]);
}
try {
new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(t0.shiftedBy(2), t0.shiftedBy(6), 0.001, 0.0001).
setTrajectory(InertialFrameId.EME2000,
pv, 2, CartesianDerivativesFilter.USE_PV,
q, 2, AngularDerivativesFilter.USE_R);
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
Assert.assertEquals(t0.shiftedBy(2), re.getParts()[0]);
}
try {
new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(t0.shiftedBy(4), t0.shiftedBy(9), 0.001, 0.0001).
setTrajectory(InertialFrameId.EME2000,
pv, 2, CartesianDerivativesFilter.USE_PV,
q, 2, AngularDerivativesFilter.USE_R);
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
Assert.assertEquals(t0.shiftedBy(9), re.getParts()[0]);
}
try {
new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(t0.shiftedBy(4), t0.shiftedBy(12), 0.001, 0.0001).
setTrajectory(InertialFrameId.EME2000,
pv, 2, CartesianDerivativesFilter.USE_PV,
q, 2, AngularDerivativesFilter.USE_R);
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
Assert.assertEquals(t0.shiftedBy(12), re.getParts()[0]);
}
}
@Test
public void testInterpolatorDump()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = createEarth();
final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension);
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0x84186d1344722b8fl,
FastMath.toRadians(1.0), 257);
RuggedBuilder original = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
original.storeInterpolator(bos);
Assert.assertTrue(bos.size() > 100000);
Assert.assertTrue(bos.size() < 200000);
GeodeticPoint[] gpOriginal = original.build().directLocation("line", 100);
RuggedBuilder recovered = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTrajectoryAndTimeSpan(new ByteArrayInputStream(bos.toByteArray())).
addLineSensor(lineSensor);
GeodeticPoint[] gpRecovered = recovered.build().directLocation("line", 100);
for (int i = 0; i < gpOriginal.length; ++i) {
Vector3D pOriginal = earth.transform(gpOriginal[i]);
Vector3D pRecovered = earth.transform(gpRecovered[i]);
Assert.assertEquals(0.0, Vector3D.distance(pOriginal, pRecovered), 1.0e-15);
}
}
@Test
public void testInterpolatorCannotDump()
throws URISyntaxException, IOException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = createEarth();
final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension);
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
RuggedBuilder original = new RuggedBuilder().
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R);
FileOutputStream fos = new FileOutputStream(tempFolder.newFile());
fos.close();
try {
original.storeInterpolator(fos);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(IOException.class, re.getCause().getClass());
}
}
@Test
public void testInterpolatorDumpWrongFrame()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = createEarth();
final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension);
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
RuggedBuilder original = new RuggedBuilder().
setDigitalElevationModel(null, -1).
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
original.storeInterpolator(bos);
Assert.assertTrue(bos.size() > 100000);
Assert.assertTrue(bos.size() < 200000);
for (BodyRotatingFrameId bId : Arrays.asList(BodyRotatingFrameId.GTOD,
BodyRotatingFrameId.ITRF_EQUINOX)) {
try {
new RuggedBuilder().
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.WGS84, bId).
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,
re.getSpecifier());
}
}
}
@Test
public void testInterpolatorNotADump()
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
// the following array is a real serialization file corresponding to the following
// made-up empty class that does not exist in Rugged:
// public class NonExistentClass implements java.io.Serializable {
// private static final long serialVersionUID = -1;
// }
byte[] nonExistentClass = new byte[] {
-84, -19, 0, 5, 115, 114,
0, 16, 78, 111, 110, 69,
120, 105, 115, 116, 101, 110,
116, 67, 108, 97, 115, 115,
-1, -1, -1, -1, -1, -1,
-1, -1, 2, 0, 0, 120,
112
};
// the following array is a real serialization file of object Integer.valueOf(1)
byte[] integerOne = new byte[] {
-84, -19, 0, 5, 115, 114,
0, 17, 106, 97, 118, 97,
46, 108, 97, 110, 103, 46,
73, 110, 116, 101, 103, 101,
114, 18, -30, -96, -92, -9,
-127,-121, 56, 2, 0, 1,
73, 0, 5, 118, 97, 108,
117, 101, 120, 114, 0, 16,
106, 97, 118, 97, 46, 108,
97, 110, 103, 46, 78, 117,
109, 98, 101, 114,-122, -84,
-107, 29, 11,-108, -32,-117,
2, 0, 0, 120, 112, 0,
0, 0, 1
};
// the following array is a truncation of the previous one
byte[] truncatedDump = new byte[] {
-84, -19, 0, 5, 115, 114,
0, 17, 106, 97, 118, 97
};
byte[] notSerialization = new byte[] {
1, 2, 3, 4, 5, 6
};
for (byte[] array : Arrays.asList(nonExistentClass, integerOne, truncatedDump, notSerialization)) {
try {
new RuggedBuilder().setTrajectoryAndTimeSpan(new ByteArrayInputStream(array));
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.NOT_INTERPOLATOR_DUMP_DATA,
re.getSpecifier());
if (array == nonExistentClass) {
Assert.assertEquals(ClassNotFoundException.class, re.getCause().getClass());
} else if (array == integerOne) {
Assert.assertEquals(ClassCastException.class, re.getCause().getClass());
} else if (array == truncatedDump) {
Assert.assertEquals(EOFException.class, re.getCause().getClass());
} else if (array == notSerialization) {
Assert.assertEquals(StreamCorruptedException.class, re.getCause().getClass());
}
}
}
}
protected void addSatellitePV(TimeScale gps, Frame eme2000, Frame itrf,
ArrayList<TimeStampedPVCoordinates> satellitePVList,
String absDate,
double px, double py, double pz, double vx, double vy, double vz) {
AbsoluteDate ephemerisDate = new AbsoluteDate(absDate, gps);
Vector3D position = new Vector3D(px, py, pz);
Vector3D velocity = new Vector3D(vx, vy, vz);
PVCoordinates pvITRF = new PVCoordinates(position, velocity);
Transform transform = itrf.getTransformTo(eme2000, ephemerisDate);
Vector3D pEME2000 = transform.transformPosition(pvITRF.getPosition());
Vector3D vEME2000 = transform.transformVector(pvITRF.getVelocity());
satellitePVList.add(new TimeStampedPVCoordinates(ephemerisDate, pEME2000, vEME2000, Vector3D.ZERO));
}
protected void addSatelliteQ(TimeScale gps, ArrayList<TimeStampedAngularCoordinates> satelliteQList, String absDate, double q0, double q1, double q2,
double q3) {
AbsoluteDate attitudeDate = new AbsoluteDate(absDate, gps);
Rotation rotation = new Rotation(q0, q1, q2, q3, true);
TimeStampedAngularCoordinates pair =
new TimeStampedAngularCoordinates(attitudeDate, rotation, Vector3D.ZERO, Vector3D.ZERO);
satelliteQList.add(pair);
}
private BodyShape createEarth() {
return new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, true));
}
private NormalizedSphericalHarmonicsProvider createGravityField() {
return GravityFieldFactory.getNormalizedProvider(12, 12);
}
private Orbit createOrbit(double mu) {
// the following orbital parameters have been computed using
// Orekit tutorial about phasing, using the following configuration:
//
// orbit.date = 2012-01-01T00:00:00.000
// phasing.orbits.number = 143
// phasing.days.number = 10
// sun.synchronous.reference.latitude = 0
// sun.synchronous.reference.ascending = false
// sun.synchronous.mean.solar.time = 10:30:00
// gravity.field.degree = 12
// gravity.field.order = 12
AbsoluteDate date = new AbsoluteDate("2012-01-01T00:00:00.000", TimeScalesFactory.getUTC());
Frame eme2000 = FramesFactory.getEME2000();
return new CircularOrbit(7173352.811913891,
-4.029194321683225E-4, 0.0013530362644647786,
FastMath.toRadians(98.63218182243709),
FastMath.toRadians(77.55565567747836),
FastMath.PI, PositionAngle.TRUE,
eme2000, date, mu);
}
private Propagator createPropagator(BodyShape earth,
NormalizedSphericalHarmonicsProvider gravityField,
Orbit orbit) {
AttitudeProvider yawCompensation = new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth));
SpacecraftState state = new SpacecraftState(orbit,
yawCompensation.getAttitude(orbit,
orbit.getDate(),
orbit.getFrame()),
1180.0);
// numerical model for improving orbit
OrbitType type = OrbitType.CIRCULAR;
double[][] tolerances = NumericalPropagator.tolerances(0.1, orbit, type);
DormandPrince853Integrator integrator =
new DormandPrince853Integrator(1.0e-4 * orbit.getKeplerianPeriod(),
1.0e-1 * orbit.getKeplerianPeriod(),
tolerances[0], tolerances[1]);
integrator.setInitialStepSize(1.0e-2 * orbit.getKeplerianPeriod());
NumericalPropagator numericalPropagator = new NumericalPropagator(integrator);
numericalPropagator.addForceModel(new HolmesFeatherstoneAttractionModel(earth.getBodyFrame(), gravityField));
numericalPropagator.addForceModel(new ThirdBodyAttraction(CelestialBodyFactory.getSun()));
numericalPropagator.addForceModel(new ThirdBodyAttraction(CelestialBodyFactory.getMoon()));
numericalPropagator.setOrbitType(type);
numericalPropagator.setInitialState(state);
numericalPropagator.setAttitudeProvider(yawCompensation);
return numericalPropagator;
}
private TimeDependentLOS createLOSPerfectLine(Vector3D center, Vector3D normal, double halfAperture, int n) {
List<Vector3D> list = new ArrayList<Vector3D>(n);
for (int i = 0; i < n; ++i) {
double alpha = (halfAperture * (2 * i + 1 - n)) / (n - 1);
list.add(new Rotation(normal, alpha, RotationConvention.VECTOR_OPERATOR).applyTo(center));
}
return new LOSBuilder(list).build();
}
private TimeStampedPVCoordinates createPV(AbsoluteDate t0, double dt,
double px, double py, double pz,
double vx, double vy, double vz) {
return new TimeStampedPVCoordinates(t0.shiftedBy(dt),
new Vector3D(px, py, pz),
new Vector3D(vx, vy, vz),
Vector3D.ZERO);
}
private TimeStampedAngularCoordinates createQ(AbsoluteDate t0, double dt,
double q0, double q1, double q2, double q3) {
return new TimeStampedAngularCoordinates(t0.shiftedBy(dt),
new Rotation(q0, q1, q2, q3, true),
Vector3D.ZERO, Vector3D.ZERO);
}
private List<TimeStampedPVCoordinates> orbitToPV(Orbit orbit, BodyShape earth,
AbsoluteDate minDate, AbsoluteDate maxDate,
double step) {
Propagator propagator = new KeplerianPropagator(orbit);
propagator.setAttitudeProvider(new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth)));
propagator.propagate(minDate);
final List<TimeStampedPVCoordinates> list = new ArrayList<TimeStampedPVCoordinates>();
propagator.getMultiplexer().add(step, currentState -> list.add(new TimeStampedPVCoordinates(currentState.getDate(),
currentState.getPVCoordinates().getPosition(),
currentState.getPVCoordinates().getVelocity(),
Vector3D.ZERO)));
propagator.propagate(maxDate);
return list;
}
private List<TimeStampedAngularCoordinates> orbitToQ(Orbit orbit, BodyShape earth,
AbsoluteDate minDate, AbsoluteDate maxDate,
double step) {
Propagator propagator = new KeplerianPropagator(orbit);
propagator.setAttitudeProvider(new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth)));
propagator.propagate(minDate);
final List<TimeStampedAngularCoordinates> list = new ArrayList<TimeStampedAngularCoordinates>();
propagator.getMultiplexer().add(step, currentState -> list.add(new TimeStampedAngularCoordinates(currentState.getDate(),
currentState.getAttitude().getRotation(),
Vector3D.ZERO, Vector3D.ZERO)));
propagator.propagate(maxDate);
return list;
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.hipparchus.analysis.differentiation.DSFactory;
import org.hipparchus.analysis.differentiation.FiniteDifferencesDifferentiator;
import org.hipparchus.analysis.differentiation.Gradient;
import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.RotationConvention;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.stat.descriptive.StreamingStatistics;
import org.hipparchus.stat.descriptive.rank.Percentile;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.orekit.bodies.BodyShape;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.errors.OrekitException;
import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.orbits.Orbit;
import org.orekit.propagation.EphemerisGenerator;
import org.orekit.propagation.Propagator;
import org.orekit.rugged.TestUtils;
import org.orekit.rugged.adjustment.GroundOptimizationProblemBuilder;
import org.orekit.rugged.adjustment.measurements.Observables;
import org.orekit.rugged.adjustment.util.InitInterRefiningTest;
import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.errors.RuggedMessages;
import org.orekit.rugged.intersection.IgnoreDEMAlgorithm;
import org.orekit.rugged.intersection.IntersectionAlgorithm;
import org.orekit.rugged.linesensor.LineDatation;
import org.orekit.rugged.linesensor.LineSensor;
import org.orekit.rugged.linesensor.LinearLineDatation;
import org.orekit.rugged.linesensor.SensorPixel;
import org.orekit.rugged.los.FixedRotation;
import org.orekit.rugged.los.LOSBuilder;
import org.orekit.rugged.los.TimeDependentLOS;
import org.orekit.rugged.raster.RandomLandscapeUpdater;
import org.orekit.rugged.raster.TileUpdater;
import org.orekit.rugged.raster.VolcanicConeElevationUpdater;
import org.orekit.rugged.refraction.AtmosphericRefraction;
import org.orekit.rugged.utils.DerivativeGenerator;
import org.orekit.rugged.utils.NormalizedGeodeticPoint;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.AngularDerivativesFilter;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.ParameterDriver;
import org.orekit.utils.TimeStampedAngularCoordinates;
import org.orekit.utils.TimeStampedPVCoordinates;
public class RuggedTest {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
// the following test is disabled by default
// it is only used to check timings, and also creates a large (66M) temporary file
@Ignore
@Test
public void testMayonVolcanoTiming()
throws URISyntaxException {
long t0 = System.currentTimeMillis();
int dimension = 2000;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
BodyShape earth = TestUtils.createEarth();
NormalizedSphericalHarmonicsProvider gravityField = TestUtils.createGravityField();
Orbit orbit = TestUtils.createOrbit(gravityField.getMu());
// Mayon Volcano location according to Wikipedia: 13°15′24″N 123°41′6″E
GeodeticPoint summit =
new GeodeticPoint(FastMath.toRadians(13.25667), FastMath.toRadians(123.685), 2463.0);
VolcanicConeElevationUpdater updater =
new VolcanicConeElevationUpdater(summit,
FastMath.toRadians(30.0), 16.0,
FastMath.toRadians(1.0), 1201);
final AbsoluteDate crossing = new AbsoluteDate("2012-01-06T02:27:16.139", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I,
FastMath.toRadians(10.0), dimension).
build();
// linear datation model: at reference time we get line 1000, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
Propagator propagator = TestUtils.createPropagator(earth, gravityField, orbit);
propagator.propagate(lineDatation.getDate(firstLine).shiftedBy(-1.0));
final EphemerisGenerator generator = propagator.getEphemerisGenerator();
propagator.propagate(lineDatation.getDate(lastLine).shiftedBy(+1.0));
Propagator ephemeris = generator.getGeneratedEphemeris();
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(lineDatation.getDate(firstLine), lineDatation.getDate(lastLine), 0.001, 5.0).
setTrajectory(1.0 / lineDatation.getRate(0.0),
8, CartesianDerivativesFilter.USE_PV,AngularDerivativesFilter.USE_R,
ephemeris).
addLineSensor(lineSensor).
build();
try {
int size = (lastLine - firstLine) * los.getNbPixels() * 3 * Integer.SIZE / 8;
RandomAccessFile out = new RandomAccessFile(tempFolder.newFile(), "rw");
MappedByteBuffer buffer = out.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, size);
long t1 = System.currentTimeMillis();
int pixels = 0;
for (double line = firstLine; line < lastLine; line++) {
GeodeticPoint[] gp = rugged.directLocation("line", line);
for (int i = 0; i < gp.length; ++i) {
final int latCode = (int) FastMath.rint(FastMath.scalb(gp[i].getLatitude(), 29));
final int lonCode = (int) FastMath.rint(FastMath.scalb(gp[i].getLongitude(), 29));
final int altCode = (int) FastMath.rint(FastMath.scalb(gp[i].getAltitude(), 17));
buffer.putInt(latCode);
buffer.putInt(lonCode);
buffer.putInt(altCode);
}
pixels += los.getNbPixels();
if (line % 100 == 0) {
System.out.format(Locale.US, "%5.0f%n", line);
}
}
long t2 = System.currentTimeMillis();
out.close();
int sizeM = size / (1024 * 1024);
System.out.format(Locale.US,
"%n%n%5dx%5d:%n" +
" Orekit initialization and DEM creation : %5.1fs%n" +
" direct location and %3dM grid writing: %5.1fs (%.1f px/s)%n",
lastLine - firstLine, los.getNbPixels(),
1.0e-3 * (t1 - t0), sizeM, 1.0e-3 * (t2 - t1), pixels / (1.0e-3 * (t2 - t1)));
} catch (IOException ioe) {
Assert.fail(ioe.getLocalizedMessage());
}
}
@Test
public void testLightTimeCorrection()
throws URISyntaxException {
int dimension = 400;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-07T11:21:15.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I,
FastMath.toRadians(10.0), dimension).build();
// linear datation model: at reference time we get line 200, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
RuggedBuilder builder = new RuggedBuilder().
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.IERS2003, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor);
Rugged rugged = builder.build();
Assert.assertEquals(1, rugged.getLineSensors().size());
Assert.assertTrue(lineSensor == rugged.getLineSensor("line"));
try {
rugged.getLineSensor("dummy");
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.UNKNOWN_SENSOR, re.getSpecifier());
Assert.assertEquals("dummy", re.getParts()[0]);
}
Assert.assertEquals(7176419.526,
rugged.getScToInertial(lineSensor.getDate(dimension / 2)).getTranslation().getNorm(),
1.0e-3);
Assert.assertEquals(0.0,
rugged.getBodyToInertial(lineSensor.getDate(dimension / 2)).getTranslation().getNorm(),
1.0e-3);
Assert.assertEquals(0.0,
rugged.getInertialToBody(lineSensor.getDate(dimension / 2)).getTranslation().getNorm(),
1.0e-3);
builder.setLightTimeCorrection(true);
builder.setAberrationOfLightCorrection(false);
rugged = builder.build();
GeodeticPoint[] gpWithLightTimeCorrection = rugged.directLocation("line", 200);
builder.setLightTimeCorrection(false);
builder.setAberrationOfLightCorrection(false);
rugged = builder.build();
GeodeticPoint[] gpWithoutLightTimeCorrection = rugged.directLocation("line", 200);
for (int i = 0; i < gpWithLightTimeCorrection.length; ++i) {
Vector3D pWith = earth.transform(gpWithLightTimeCorrection[i]);
Vector3D pWithout = earth.transform(gpWithoutLightTimeCorrection[i]);
Assert.assertTrue(Vector3D.distance(pWith, pWithout) > 1.23);
Assert.assertTrue(Vector3D.distance(pWith, pWithout) < 1.27);
}
}
@Test
public void testAberrationOfLightCorrection()
throws URISyntaxException {
int dimension = 400;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-07T11:46:35.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I,
FastMath.toRadians(10.0), dimension).build();
// linear datation model: at reference time we get line 200, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
RuggedBuilder builder = new RuggedBuilder().
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor).
setLightTimeCorrection(false).
setAberrationOfLightCorrection(true);
Rugged rugged = builder.build();
GeodeticPoint[] gpWithAberrationOfLightCorrection = rugged.directLocation("line", 200);
builder.setLightTimeCorrection(false);
builder.setAberrationOfLightCorrection(false);
rugged = builder.build();
GeodeticPoint[] gpWithoutAberrationOfLightCorrection = rugged.directLocation("line", 200);
for (int i = 0; i < gpWithAberrationOfLightCorrection.length; ++i) {
Vector3D pWith = earth.transform(gpWithAberrationOfLightCorrection[i]);
Vector3D pWithout = earth.transform(gpWithoutAberrationOfLightCorrection[i]);
Assert.assertTrue(Vector3D.distance(pWith, pWithout) > 20.0);
Assert.assertTrue(Vector3D.distance(pWith, pWithout) < 20.5);
}
}
@Test
public void testFlatBodyCorrection()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension).build();
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
RuggedBuilder builder = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor);
GeodeticPoint[] gpWithFlatBodyCorrection =
builder.setAlgorithm(AlgorithmId.DUVENHAGE).build().directLocation("line", 100);
GeodeticPoint[] gpWithoutFlatBodyCorrection =
builder.setAlgorithm(AlgorithmId.DUVENHAGE_FLAT_BODY).build().directLocation("line", 100);
StreamingStatistics stats = new StreamingStatistics();
for (int i = 0; i < gpWithFlatBodyCorrection.length; ++i) {
Vector3D pWith = earth.transform(gpWithFlatBodyCorrection[i]);
Vector3D pWithout = earth.transform(gpWithoutFlatBodyCorrection[i]);
stats.addValue(Vector3D.distance(pWith, pWithout));
}
Assert.assertEquals( 0.004, stats.getMin(), 1.0e-3);
Assert.assertEquals(28.344, stats.getMax(), 1.0e-3);
Assert.assertEquals( 4.801, stats.getMean(), 1.0e-3);
}
@Test
public void testLocationSinglePoint()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension).build();
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor).build();
GeodeticPoint[] gpLine = rugged.directLocation("line", 100);
for (int i = 0; i < gpLine.length; ++i) {
GeodeticPoint gpPixel =
rugged.directLocation(lineSensor.getDate(100), lineSensor.getPosition(),
lineSensor.getLOS(lineSensor.getDate(100), i));
Assert.assertEquals(gpLine[i].getLatitude(), gpPixel.getLatitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getLongitude(), gpPixel.getLongitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getAltitude(), gpPixel.getAltitude(), 1.0e-10);
}
}
@Test
public void testLocationsinglePointNoCorrections()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension).build();
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
setAberrationOfLightCorrection(false).
setLightTimeCorrection(false).
addLineSensor(lineSensor).
build();
GeodeticPoint[] gpLine = rugged.directLocation("line", 100);
for (int i = 0; i < gpLine.length; ++i) {
GeodeticPoint gpPixel =
rugged.directLocation(lineSensor.getDate(100), lineSensor.getPosition(),
lineSensor.getLOS(lineSensor.getDate(100), i));
Assert.assertEquals(gpLine[i].getLatitude(), gpPixel.getLatitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getLongitude(), gpPixel.getLongitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getAltitude(), gpPixel.getAltitude(), 1.0e-10);
}
}
@Test
public void testBasicScan()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension).build();
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xe12ef744f224cf43l,
FastMath.toRadians(1.0), 257);
RuggedBuilder builder = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor);
GeodeticPoint[] gpDuvenhage =
builder.setAlgorithm(AlgorithmId.DUVENHAGE).build().directLocation("line", 100);
GeodeticPoint[] gpBasicScan =
builder.setAlgorithm(AlgorithmId.BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY).build().directLocation("line", 100);
double[] data = new double[gpDuvenhage.length];
for (int i = 0; i < gpDuvenhage.length; ++i) {
Vector3D pDuvenhage = earth.transform(gpDuvenhage[i]);
Vector3D pBasicScan = earth.transform(gpBasicScan[i]);
data[i] = Vector3D.distance(pDuvenhage, pBasicScan);
}
Assert.assertEquals(0.0, new Percentile(99).evaluate(data), 5.1e-4);
}
// the following test is disabled by default
// it is only used to check timings, and also creates a large (38M) temporary file
@Ignore
@Test
public void testInverseLocationTiming()
throws URISyntaxException {
long t0 = System.currentTimeMillis();
int dimension = 2000;
int nbSensors = 3;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
List<LineSensor> sensors = new ArrayList<LineSensor>();
for (int i = 0; i < nbSensors; ++i) {
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking roughly at 50° roll (sensor-dependent), 5.2" per pixel
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0 - 0.001 * i),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians((dimension/2.) * 5.2 / 3600.0), dimension).build();
// linear datation model: at reference time we get roughly middle line, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, i + dimension / 2, 1.0 / 1.5e-3);
sensors.add(new LineSensor("line-" + i, lineDatation, position, los));
}
int firstLine = 0;
int lastLine = dimension;
AbsoluteDate minDate = sensors.get(0).getDate(firstLine).shiftedBy(-1.0);
AbsoluteDate maxDate = sensors.get(sensors.size() - 1).getDate(lastLine).shiftedBy(+1.0);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
RuggedBuilder builder = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R);
builder.setLightTimeCorrection(true);
builder.setAberrationOfLightCorrection(true);
for (LineSensor lineSensor : sensors) {
builder.addLineSensor(lineSensor);
}
Rugged rugged = builder.build();
double lat0 = FastMath.toRadians(-22.9);
double lon0 = FastMath.toRadians(142.4);
double delta = FastMath.toRadians(0.5);
try {
long size = nbSensors * dimension * dimension * 2l * Integer.SIZE / 8l;
RandomAccessFile out = new RandomAccessFile(tempFolder.newFile(), "rw");
MappedByteBuffer buffer = out.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, size);
long t1 = System.currentTimeMillis();
int goodPixels = 0;
int badPixels = 0;
for (final LineSensor lineSensor : sensors) {
for (int i = 0; i < dimension; ++i) {
double latitude = lat0 + (i * delta) / dimension;
if (i %100 == 0) {
System.out.println(lineSensor.getName() + " " + i);
}
for (int j = 0; j < dimension; ++j) {
double longitude = lon0 + (j * delta) / dimension;
SensorPixel sp = rugged.inverseLocation(lineSensor.getName(), latitude, longitude,
firstLine, lastLine);
if (sp == null) {
++badPixels;
buffer.putInt(-1);
buffer.putInt(-1);
} else {
++goodPixels;
final int lineCode = (int) FastMath.rint(FastMath.scalb(sp.getLineNumber(), 16));
final int pixelCode = (int) FastMath.rint(FastMath.scalb(sp.getPixelNumber(), 16));
buffer.putInt(lineCode);
buffer.putInt(pixelCode);
}
}
}
}
long t2 = System.currentTimeMillis();
out.close();
int sizeM = (int) (size / (1024l * 1024l));
System.out.format(Locale.US,
"%n%n%5dx%5d, %d sensors:%n" +
" Orekit initialization and DEM creation : %5.1fs%n" +
" inverse location and %3dM grid writing: %5.1fs (%.1f px/s, %.1f%% covered)%n",
dimension, dimension, nbSensors,
1.0e-3 * (t1 - t0), sizeM, 1.0e-3 * (t2 - t1),
(badPixels + goodPixels) / (1.0e-3 * (t2 - t1)),
(100.0 * goodPixels) / (goodPixels + badPixels));
} catch (IOException ioe) {
Assert.fail(ioe.getLocalizedMessage());
}
}
@Test
public void testInverseLocation()
throws URISyntaxException {
checkInverseLocation(2000, false, false, 4.0e-7, 5.0e-6);
checkInverseLocation(2000, false, true, 1.0e-5, 2.0e-7);
checkInverseLocation(2000, true, false, 4.0e-7, 4.0e-7);
checkInverseLocation(2000, true, true, 2.0e-5, 3.0e-7);
}
@Test
public void testDateLocation()
throws URISyntaxException {
checkDateLocation(2000, false, false, 7.0e-7);
checkDateLocation(2000, false, true, 2.0e-5);
checkDateLocation(2000, true, false, 8.0e-7);
checkDateLocation(2000, true, true, 3.0e-6);
}
@Test
public void testLineDatation()
throws URISyntaxException {
checkLineDatation(2000, 7.0e-7);
checkLineDatation(10000, 8.0e-7);
}
@Test
public void testInverseLocNearLineEnd() throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
Vector3D offset = Vector3D.ZERO;
TimeScale gps = TimeScalesFactory.getGPS();
Frame eme2000 = FramesFactory.getEME2000();
Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
ArrayList<TimeStampedAngularCoordinates> satelliteQList = new ArrayList<TimeStampedAngularCoordinates>();
ArrayList<TimeStampedPVCoordinates> satellitePVList = new ArrayList<TimeStampedPVCoordinates>();
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T16:58:42.592937", -0.340236d, 0.333952d, -0.844012d, -0.245684d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T16:59:06.592937", -0.354773d, 0.329336d, -0.837871d, -0.252281d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T16:59:30.592937", -0.369237d, 0.324612d, -0.831445d, -0.258824d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T16:59:54.592937", -0.3836d, 0.319792d, -0.824743d, -0.265299d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T17:00:18.592937", -0.397834d, 0.314883d, -0.817777d, -0.271695d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T17:00:42.592937", -0.411912d, 0.309895d, -0.810561d, -0.278001d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T17:01:06.592937", -0.42581d, 0.304838d, -0.803111d, -0.284206d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T17:01:30.592937", -0.439505d, 0.299722d, -0.795442d, -0.290301d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T17:01:54.592937", -0.452976d, 0.294556d, -0.787571d, -0.296279d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2009-12-11T17:02:18.592937", -0.466207d, 0.28935d, -0.779516d, -0.302131d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T16:58:42.592937", -726361.466d, -5411878.485d, 4637549.599d, -2068.995d, -4500.601d, -5576.736d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T16:59:04.192937", -779538.267d, -5506500.533d, 4515934.894d, -2058.308d, -4369.521d, -5683.906d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T16:59:25.792937", -832615.368d, -5598184.195d, 4392036.13d, -2046.169d, -4236.279d, -5788.201d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T16:59:47.392937", -885556.748d, -5686883.696d, 4265915.971d, -2032.579d, -4100.944d, -5889.568d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:00:08.992937", -938326.32d, -5772554.875d, 4137638.207d, -2017.537d, -3963.59d, -5987.957d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:00:30.592937", -990887.942d, -5855155.21d, 4007267.717d, -2001.046d, -3824.291d, -6083.317d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:00:52.192937", -1043205.448d, -5934643.836d, 3874870.441d, -1983.107d, -3683.122d, -6175.6d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:01:13.792937", -1095242.669d, -6010981.571d, 3740513.34d, -1963.723d, -3540.157d, -6264.76d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:01:35.392937", -1146963.457d, -6084130.93d, 3604264.372d, -1942.899d, -3395.473d, -6350.751d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:01:56.992937", -1198331.706d, -6154056.146d, 3466192.446d, -1920.64d, -3249.148d, -6433.531d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2009-12-11T17:02:18.592937", -1249311.381d, -6220723.191d, 3326367.397d, -1896.952d, -3101.26d, -6513.056d);
TileUpdater updater = new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l, FastMath.toRadians(1.0), 257);
RuggedBuilder builder = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(satellitePVList.get(0).getDate(), satellitePVList.get(satellitePVList.size() - 1).getDate(), 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
satellitePVList, 8, CartesianDerivativesFilter.USE_PV,
satelliteQList, 8, AngularDerivativesFilter.USE_R);
List<Vector3D> lineOfSight = new ArrayList<Vector3D>();
lineOfSight.add(new Vector3D(-0.011204, 0.181530, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181518, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181505, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181492, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181480, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181467, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181455, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181442, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181430, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181417, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181405, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.181392, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149762, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149749, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149737, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149724, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149712, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149699, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149686, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149674, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149661, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149649, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149636, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149624, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149611, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149599, 1d).normalize());
lineOfSight.add(new Vector3D(-0.011204, 0.149586, 1d).normalize());
AbsoluteDate absDate = new AbsoluteDate("2009-12-11T16:58:51.593", gps);
LinearLineDatation lineDatation = new LinearLineDatation(absDate, 1d, 638.5696040868454);
LineSensor lineSensor = new LineSensor("perfect-line", lineDatation, offset,
new LOSBuilder(lineOfSight).build());
builder.addLineSensor(lineSensor);
Rugged rugged = builder.build();
GeodeticPoint point1 = new GeodeticPoint(0.7053784581520293, -1.7354535645320581, 691.856741468848);
SensorPixel sensorPixel1 = rugged.inverseLocation(lineSensor.getName(), point1, 1, 131328);
Assert.assertEquals( 2.01474, sensorPixel1.getLineNumber(), 1.0e-5);
Assert.assertEquals( 2.09271, sensorPixel1.getPixelNumber(), 1.0e-5);
GeodeticPoint point2 = new GeodeticPoint(0.704463899881073, -1.7303503789334154, 648.9200602492216);
SensorPixel sensorPixel2 = rugged.inverseLocation(lineSensor.getName(), point2, 1, 131328);
Assert.assertEquals( 2.02185, sensorPixel2.getLineNumber(), 1.0e-5);
Assert.assertEquals( 27.53008, sensorPixel2.getPixelNumber(), 1.0e-5);
GeodeticPoint point3 = new GeodeticPoint(0.7009593480939814, -1.7314283804521957, 588.3075485689468);
SensorPixel sensorPixel3 = rugged.inverseLocation(lineSensor.getName(), point3, 1, 131328);
Assert.assertEquals(2305.26101, sensorPixel3.getLineNumber(), 1.0e-5);
Assert.assertEquals( 27.18381, sensorPixel3.getPixelNumber(), 1.0e-5);
GeodeticPoint point4 = new GeodeticPoint(0.7018731669637096, -1.73651769725183, 611.2759403696498);
SensorPixel sensorPixel4 = rugged.inverseLocation(lineSensor.getName(), point4, 1, 131328);
Assert.assertEquals(2305.25436, sensorPixel4.getLineNumber(), 1.0e-5);
Assert.assertEquals( 1.54447, sensorPixel4.getPixelNumber(), 1.0e-5);
}
@Test
public void testInverseLoc() throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
Vector3D offset = Vector3D.ZERO;
TimeScale gps = TimeScalesFactory.getGPS();
Frame eme2000 = FramesFactory.getEME2000();
Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
ArrayList<TimeStampedAngularCoordinates> satelliteQList = new ArrayList<TimeStampedAngularCoordinates>();
ArrayList<TimeStampedPVCoordinates> satellitePVList = new ArrayList<TimeStampedPVCoordinates>();
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:27", -0.327993d, -0.715194d, -0.56313d, 0.252592d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:29", -0.328628d, -0.71494d, -0.562769d, 0.25329d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:31", -0.329263d, -0.714685d, -0.562407d, 0.253988d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:33", -0.329898d, -0.714429d, -0.562044d, 0.254685d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:35", -0.330532d, -0.714173d, -0.561681d, 0.255383d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:37", -0.331166d, -0.713915d, -0.561318d, 0.256079d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:39", -0.3318d, -0.713657d, -0.560954d, 0.256776d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:41", -0.332434d, -0.713397d, -0.560589d, 0.257472d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:43", -0.333067d, -0.713137d, -0.560224d, 0.258168d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:16:45", -0.333699d, -0.712876d, -0.559859d, 0.258864d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:18:17", -0.36244d, -0.699935d, -0.542511d, 0.290533d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:27", -0.401688d, -0.678574d, -0.516285d, 0.334116d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:29", -0.402278d, -0.678218d, -0.515866d, 0.334776d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:31", -0.402868d, -0.677861d, -0.515447d, 0.335435d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:33", -0.403457d, -0.677503d, -0.515028d, 0.336093d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:35", -0.404046d, -0.677144d, -0.514608d, 0.336752d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:37", -0.404634d, -0.676785d, -0.514187d, 0.337409d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:39", -0.405222d, -0.676424d, -0.513767d, 0.338067d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:41", -0.40581d, -0.676063d, -0.513345d, 0.338724d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:43", -0.406397d, -0.675701d, -0.512924d, 0.339381d);
TestUtils.addSatelliteQ(gps, satelliteQList, "2013-07-07T17:20:45", -0.406983d, -0.675338d, -0.512502d, 0.340038d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:16:27.857531", -379110.393d, -5386317.278d, 4708158.61d, -1802.078d, -4690.847d, -5512.223d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:16:36.857531", -398874.476d, -5428039.968d, 4658344.906d, -1801.326d, -4636.91d, -5557.915d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:16:45.857531", -418657.992d, -5469262.453d, 4608122.145d, -1800.345d, -4582.57d, -5603.119d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:16:54.857531", -438458.554d, -5509981.109d, 4557494.737d, -1799.136d, -4527.831d, -5647.831d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:03.857531", -458273.771d, -5550192.355d, 4506467.128d, -1797.697d, -4472.698d, -5692.046d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:12.857531", -478101.244d, -5589892.661d, 4455043.798d, -1796.029d, -4417.176d, -5735.762d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:21.857531", -497938.57d, -5629078.543d, 4403229.263d, -1794.131d, -4361.271d, -5778.975d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:30.857531", -517783.34d, -5667746.565d, 4351028.073d, -1792.003d, -4304.987d, -5821.679d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:39.857531", -537633.139d, -5705893.34d, 4298444.812d, -1789.644d, -4248.329d, -5863.873d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:48.857531", -557485.549d, -5743515.53d, 4245484.097d, -1787.055d, -4191.304d, -5905.552d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:17:57.857531", -577338.146d, -5780609.846d, 4192150.579d, -1784.234d, -4133.916d, -5946.712d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:18:06.857531", -597188.502d, -5817173.047d, 4138448.941d, -1781.183d, -4076.171d, -5987.35d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:18:15.857531", -617034.185d, -5853201.943d, 4084383.899d, -1777.899d, -4018.073d, -6027.462d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:18:24.857531", -636872.759d, -5888693.393d, 4029960.2d, -1774.385d, -3959.629d, -6067.045d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:18:33.857531", -656701.786d, -5923644.307d, 3975182.623d, -1770.638d, -3900.844d, -6106.095d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:18:42.857531", -676518.822d, -5958051.645d, 3920055.979d, -1766.659d, -3841.723d, -6144.609d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:18:51.857531", -696321.424d, -5991912.417d, 3864585.108d, -1762.449d, -3782.271d, -6182.583d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:00.857531", -716107.143d, -6025223.686d, 3808774.881d, -1758.006d, -3722.495d, -6220.015d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:09.857531", -735873.528d, -6057982.563d, 3752630.2d, -1753.332d, -3662.399d, -6256.9d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:18.857531", -755618.129d, -6090186.214d, 3696155.993d, -1748.425d, -3601.99d, -6293.236d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:27.857531", -775338.49d, -6121831.854d, 3639357.221d, -1743.286d, -3541.272d, -6329.019d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:36.857531", -795032.157d, -6152916.751d, 3582238.87d, -1737.915d, -3480.252d, -6364.246d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:45.857531", -814696.672d, -6183438.226d, 3524805.957d, -1732.313d, -3418.935d, -6398.915d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:19:54.857531", -834329.579d, -6213393.652d, 3467063.525d, -1726.478d, -3357.327d, -6433.022d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:20:03.857531", -853928.418d, -6242780.453d, 3409016.644d, -1720.412d, -3295.433d, -6466.563d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:20:12.857531", -873490.732d, -6271596.108d, 3350670.411d, -1714.114d, -3233.259d, -6499.537d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:20:21.857531", -893014.061d, -6299838.148d, 3292029.951d, -1707.585d, -3170.811d, -6531.941d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:20:30.857531", -912495.948d, -6327504.159d, 3233100.411d, -1700.825d, -3108.095d, -6563.77d);
TestUtils.addSatellitePV(gps, eme2000, itrf, satellitePVList, "2013-07-07T17:20:39.857531", -931933.933d, -6354591.778d, 3173886.968d, -1693.833d, -3045.116d, -6595.024d);
List<Vector3D> lineOfSight = new ArrayList<Vector3D>();
lineOfSight.add(new Vector3D(0.0046536264d, -0.1851800945d, 1d));
lineOfSight.add(new Vector3D(0.0000001251d, -0.0002815246d, 1d));
lineOfSight.add(new Vector3D(0.0046694108d, 0.1853863933d, 1d));
AbsoluteDate absDate = new AbsoluteDate("2013-07-07T17:16:36.857", gps);
LinearLineDatation lineDatation = new LinearLineDatation(absDate, 0.03125d, 19.95565693384045);
LineSensor lineSensor = new LineSensor("QUICK_LOOK", lineDatation, offset,
new LOSBuilder(lineOfSight).build());
// in order not to have a problem when calling the pixelIsInside method (AtmosphericRefraction must be not null)
AtmosphericRefraction atmos = new AtmosphericRefraction() {
@Override
public NormalizedGeodeticPoint applyCorrection(Vector3D satPos, Vector3D satLos,
NormalizedGeodeticPoint rawIntersection, IntersectionAlgorithm algorithm) {
return rawIntersection;
}
};
atmos.deactivateComputation();
Rugged rugged = new RuggedBuilder().
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(satellitePVList.get(0).getDate(),
satellitePVList.get(satellitePVList.size() - 1).getDate(), 0.1, 10.0).
setTrajectory(InertialFrameId.EME2000,
satellitePVList, 6, CartesianDerivativesFilter.USE_P,
satelliteQList, 8, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor).
setRefractionCorrection(atmos).
build();
GeodeticPoint[] temp = rugged.directLocation("QUICK_LOOK", -250);
GeodeticPoint first = temp[0];
double minLon = first.getLongitude();
double minLat = first.getLatitude();
temp = rugged.directLocation("QUICK_LOOK", 350);
GeodeticPoint last = temp[temp.length - 1];
double maxLon = last.getLongitude();
double maxLat = last.getLatitude();
GeodeticPoint gp = new GeodeticPoint((minLat + maxLat) / 2d, (minLon + maxLon) / 2d, 0d);
SensorPixel sensorPixel = rugged.inverseLocation("QUICK_LOOK", gp, -250, 350);
Assert.assertNotNull(sensorPixel);
Assert.assertFalse(inside(rugged, null, lineSensor));
Assert.assertFalse(inside(rugged, new SensorPixel(-100, -100), lineSensor));
Assert.assertFalse(inside(rugged, new SensorPixel(-100, +100), lineSensor));
Assert.assertFalse(inside(rugged, new SensorPixel(+100, -100), lineSensor));
Assert.assertFalse(inside(rugged, new SensorPixel(+100, +100), lineSensor));
Assert.assertTrue(inside(rugged, new SensorPixel(0.2, 0.3), lineSensor));
}
private boolean inside(final Rugged rugged, final SensorPixel sensorPixel, LineSensor lineSensor) {
try {
final Method inside =
Rugged.class.getDeclaredMethod("pixelIsInside",
SensorPixel.class,
LineSensor.class);
inside.setAccessible(true);
return ((Boolean) inside.invoke(rugged, sensorPixel, lineSensor)).booleanValue();
} catch (NoSuchMethodException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException e) {
Assert.fail(e.getLocalizedMessage());
return false;
}
}
@Test
public void testInverseLocCurvedLine()
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
int dimension = 200;
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at nadir, 5.2" per pixel, 3" sagitta
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSCurvedLine(Vector3D.PLUS_K, Vector3D.PLUS_I,
FastMath.toRadians((dimension/2.) * 5.2 / 3600.0),
FastMath.toRadians(3.0 / 3600.0),
dimension);
// linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("curved", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine).shiftedBy(-1.0);
AbsoluteDate maxDate = lineSensor.getDate(lastLine).shiftedBy(+1.0);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.3, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor).
build();
int lineNumber = 97;
GeodeticPoint[] gp = rugged.directLocation("curved", lineNumber);
for (int i = 0; i < gp.length; ++i) {
SensorPixel pixel = rugged.inverseLocation("curved", gp[i], firstLine, lastLine);
Assert.assertEquals(lineNumber, pixel.getLineNumber(), 5.0e-4);
Assert.assertEquals(i, pixel.getPixelNumber(), 3.1e-7);
}
}
private void checkInverseLocation(int dimension, boolean lightTimeCorrection, boolean aberrationOfLightCorrection,
double maxLineError, double maxPixelError)
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, 5.2" per pixel
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(5.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I,
FastMath.toRadians((dimension/2.) * 5.2 / 3600.0), dimension).build();
// In fact the pixel size = 5.2" as we construct the LOS with the full line (dimension) instead of dimension/2
// linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine).shiftedBy(-1.0);
AbsoluteDate maxDate = lineSensor.getDate(lastLine).shiftedBy(+1.0);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.3, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
setLightTimeCorrection(lightTimeCorrection).
setAberrationOfLightCorrection(aberrationOfLightCorrection).
addLineSensor(lineSensor).
build();
double referenceLine = 0.87654 * dimension;
GeodeticPoint[] gp = rugged.directLocation("line", referenceLine);
for (double p = 0; p < gp.length - 1; p += 1.0) {
int i = (int) FastMath.floor(p);
double d = p - i;
SensorPixel sp = rugged.inverseLocation("line",
(1 - d) * gp[i].getLatitude() + d * gp[i + 1].getLatitude(),
(1 - d) * gp[i].getLongitude() + d * gp[i + 1].getLongitude(),
0, dimension);
Assert.assertEquals(referenceLine, sp.getLineNumber(), maxLineError);
Assert.assertEquals(p, sp.getPixelNumber(), maxPixelError);
}
// point out of line (20 pixels before first pixel)
Assert.assertNull(rugged.inverseLocation("line",
21 * gp[0].getLatitude() - 20 * gp[1].getLatitude(),
21 * gp[0].getLongitude() - 20 * gp[1].getLongitude(),
0, dimension));
// point out of line (20 pixels after last pixel)
Assert.assertNull(rugged.inverseLocation("line",
-20 * gp[gp.length - 2].getLatitude() + 21 * gp[gp.length - 1].getLatitude(),
-20 * gp[gp.length - 2].getLongitude() + 21 * gp[gp.length - 1].getLongitude(),
0, dimension));
// point out of line (20 lines before first line)
GeodeticPoint[] gp0 = rugged.directLocation("line", 0);
GeodeticPoint[] gp1 = rugged.directLocation("line", 1);
Assert.assertNull(rugged.inverseLocation("line",
21 * gp0[dimension / 2].getLatitude() - 20 * gp1[dimension / 2].getLatitude(),
21 * gp0[dimension / 2].getLongitude() - 20 * gp1[dimension / 2].getLongitude(),
0, dimension));
// point out of line (20 lines after last line)
GeodeticPoint[] gp2 = rugged.directLocation("line", dimension - 2);
GeodeticPoint[] gp3 = rugged.directLocation("line", dimension - 1);
Assert.assertNull(rugged.inverseLocation("line",
-20 * gp2[dimension / 2].getLatitude() + 21 * gp3[dimension / 2].getLatitude(),
-20 * gp2[dimension / 2].getLongitude() + 21 * gp3[dimension / 2].getLongitude(),
0, dimension));
}
@Test
public void testInverseLocationDerivativesWithoutCorrections()
{
doTestInverseLocationDerivatives(2000, false, false,
8.0e-9, 3.0e-10, 5.0e-12, 9.0e-8);
}
@Test
public void testInverseLocationDerivativesWithLightTimeCorrection()
{
doTestInverseLocationDerivatives(2000, true, false,
3.0e-9, 9.0e-9, 2.1e-12, 9.0e-8);
}
@Test
public void testInverseLocationDerivativesWithAberrationOfLightCorrection()
{
doTestInverseLocationDerivatives(2000, false, true,
4.2e-10, 3.0e-10, 3.4e-12, 7.0e-8);
}
@Test
public void testInverseLocationDerivativesWithAllCorrections()
{
doTestInverseLocationDerivatives(2000, true, true,
7.0e-10, 5.0e-10, 2.0e-12, 7.0e-8);
}
/**
* @param dimension
* @param lightTimeCorrection
* @param aberrationOfLightCorrection
* @param lineTolerance
* @param pixelTolerance
* @param lineDerivativeRelativeTolerance
* @param pixelDerivativeRelativeTolerance
*/
private void doTestInverseLocationDerivatives(int dimension,
boolean lightTimeCorrection,
boolean aberrationOfLightCorrection,
double lineTolerance,
double pixelTolerance,
double lineDerivativeRelativeTolerance,
double pixelDerivativeRelativeTolerance)
{
try {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, 5.2" per pixel
Vector3D position = new Vector3D(1.5, 0, -0.2);
LOSBuilder losBuilder =
TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I,
FastMath.toRadians((dimension/2.) * 5.2 / 3600.0), dimension);
losBuilder.addTransform(new FixedRotation("roll", Vector3D.MINUS_I, 0.0));
losBuilder.addTransform(new FixedRotation("pitch", Vector3D.MINUS_J, 0.0));
TimeDependentLOS los = losBuilder.build();
// In fact the pixel size = 5.2" as we construct the LOS with the full line (dimension) instead of dimension/2
// linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
final LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine).shiftedBy(-1.0);
AbsoluteDate maxDate = lineSensor.getDate(lastLine).shiftedBy(+1.0);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.3, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
setLightTimeCorrection(lightTimeCorrection).
setAberrationOfLightCorrection(aberrationOfLightCorrection).
addLineSensor(lineSensor).
build();
// we want to adjust sensor roll and pitch angles
ParameterDriver rollDriver =
lineSensor.getParametersDrivers().
filter(driver -> driver.getName().equals("roll")).findFirst().get();
rollDriver.setSelected(true);
ParameterDriver pitchDriver =
lineSensor.getParametersDrivers().
filter(driver -> driver.getName().equals("pitch")).findFirst().get();
pitchDriver.setSelected(true);
// prepare generator
final Observables measurements = new Observables(1);
GroundOptimizationProblemBuilder optimizationPbBuilder = new GroundOptimizationProblemBuilder(Collections.singletonList(lineSensor),
measurements, rugged);
java.lang.reflect.Method getGenerator = GroundOptimizationProblemBuilder.class.getSuperclass().getDeclaredMethod("getGenerator");
getGenerator.setAccessible(true);
@SuppressWarnings("unchecked")
DerivativeGenerator<Gradient> generator = (DerivativeGenerator<Gradient>) getGenerator.invoke(optimizationPbBuilder);
double referenceLine = 0.87654 * dimension;
GeodeticPoint[] gp = rugged.directLocation("line", referenceLine);
Method inverseLoc = Rugged.class.getDeclaredMethod("inverseLocationDerivatives",
String.class, GeodeticPoint.class,
Integer.TYPE, Integer.TYPE,
DerivativeGenerator.class);
inverseLoc.setAccessible(true);
int referencePixel = (3 * dimension) / 4;
Gradient[] result =
(Gradient[]) inverseLoc.invoke(rugged,
"line", gp[referencePixel], 0, dimension,
generator);
Assert.assertEquals(referenceLine, result[0].getValue(), lineTolerance);
Assert.assertEquals(referencePixel, result[1].getValue(), pixelTolerance);
Assert.assertEquals(2, result[0].getFreeParameters());
Assert.assertEquals(1, result[0].getOrder());
// check the partial derivatives
DSFactory factory = new DSFactory(1, 1);
double h = 1.0e-6;
FiniteDifferencesDifferentiator differentiator = new FiniteDifferencesDifferentiator(8, h);
UnivariateDifferentiableFunction lineVSroll =
differentiator.differentiate((double roll) -> {
rollDriver.setValue(roll);
pitchDriver.setValue(0);
return rugged.inverseLocation("line", gp[referencePixel], 0, dimension).getLineNumber();
});
double dLdR = lineVSroll.value(factory.variable(0, 0.0)).getPartialDerivative(1);
Assert.assertEquals(dLdR, result[0].getPartialDerivative(1, 0), dLdR * lineDerivativeRelativeTolerance);
UnivariateDifferentiableFunction lineVSpitch =
differentiator.differentiate((double pitch) -> {
rollDriver.setValue(0);
pitchDriver.setValue(pitch);
return rugged.inverseLocation("line", gp[referencePixel], 0, dimension).getLineNumber();
});
double dLdP = lineVSpitch.value(factory.variable(0, 0.0)).getPartialDerivative(1);
Assert.assertEquals(dLdP, result[0].getPartialDerivative(0, 1), dLdP * lineDerivativeRelativeTolerance);
UnivariateDifferentiableFunction pixelVSroll =
differentiator.differentiate((double roll) -> {
rollDriver.setValue(roll);
pitchDriver.setValue(0);
return rugged.inverseLocation("line", gp[referencePixel], 0, dimension).getPixelNumber();
});
double dXdR = pixelVSroll.value(factory.variable(0, 0.0)).getPartialDerivative(1);
Assert.assertEquals(dXdR, result[1].getPartialDerivative(1, 0), dXdR * pixelDerivativeRelativeTolerance);
UnivariateDifferentiableFunction pixelVSpitch =
differentiator.differentiate((double pitch) -> {
rollDriver.setValue(0);
pitchDriver.setValue(pitch);
return rugged.inverseLocation("line", gp[referencePixel], 0, dimension).getPixelNumber();
});
double dXdP = pixelVSpitch.value(factory.variable(0, 0.0)).getPartialDerivative(1);
Assert.assertEquals(dXdP, result[1].getPartialDerivative(0, 1), dXdP * pixelDerivativeRelativeTolerance);
} catch (InvocationTargetException | NoSuchMethodException |
SecurityException | IllegalAccessException |
IllegalArgumentException | URISyntaxException |
OrekitException | RuggedException e) {
Assert.fail(e.getLocalizedMessage());
}
}
private void checkDateLocation(int dimension, boolean lightTimeCorrection, boolean aberrationOfLightCorrection,
double maxDateError)
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, 5.2" per pixel
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I,
FastMath.toRadians((dimension/2.) * 5.2 / 3600.0), dimension).build();
// In fact the pixel size = 5.2" as we construct the LOS with the full line (dimension) instead of dimension/2
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine).shiftedBy(-1.0);
AbsoluteDate maxDate = lineSensor.getDate(lastLine).shiftedBy(+1.0);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
setLightTimeCorrection(lightTimeCorrection).
setAberrationOfLightCorrection(aberrationOfLightCorrection).
addLineSensor(lineSensor).
build();
double referenceLine = 0.87654 * dimension;
GeodeticPoint[] gp = rugged.directLocation("line", referenceLine);
for (double p = 0; p < gp.length - 1; p += 1.0) {
int i = (int) FastMath.floor(p);
double d = p - i;
AbsoluteDate date = rugged.dateLocation("line",
(1 - d) * gp[i].getLatitude() + d * gp[i + 1].getLatitude(),
(1 - d) * gp[i].getLongitude() + d * gp[i + 1].getLongitude(),
0, dimension);
Assert.assertEquals(0.0, date.durationFrom(lineSensor.getDate(referenceLine)), maxDateError);
}
// point out of line (20 lines before first line)
GeodeticPoint[] gp0 = rugged.directLocation("line", 0);
GeodeticPoint[] gp1 = rugged.directLocation("line", 1);
Assert.assertNull(rugged.dateLocation("line",
21 * gp0[dimension / 2].getLatitude() - 20 * gp1[dimension / 2].getLatitude(),
21 * gp0[dimension / 2].getLongitude() - 20 * gp1[dimension / 2].getLongitude(),
0, dimension));
// point out of line (20 lines after last line)
GeodeticPoint[] gp2 = rugged.directLocation("line", dimension - 2);
GeodeticPoint[] gp3 = rugged.directLocation("line", dimension - 1);
Assert.assertNull(rugged.dateLocation("line",
-20 * gp2[dimension / 2].getLatitude() + 21 * gp3[dimension / 2].getLatitude(),
-20 * gp2[dimension / 2].getLongitude() + 21 * gp3[dimension / 2].getLongitude(),
0, dimension));
}
private void checkLineDatation(int dimension, double maxLineError)
throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, 2.6" per pixel
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I,
FastMath.toRadians(dimension * 2.6 / 3600.0), dimension).build();
// In fact the pixel size = 5.2" as we construct the LOS with the full line (dimension) instead of dimension/2
// linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine).shiftedBy(-1.0);
AbsoluteDate maxDate = lineSensor.getDate(lastLine).shiftedBy(+1.0);
// Recompute the lines from the date with the appropriate shift of date
double recomputedFirstLine = lineSensor.getLine(minDate.shiftedBy(+1.0));
double recomputedLastLine = lineSensor.getLine(maxDate.shiftedBy(-1.0));
Assert.assertEquals(firstLine, recomputedFirstLine, maxLineError);
Assert.assertEquals(lastLine, recomputedLastLine, maxLineError);
}
@Test
public void testDistanceBetweenLOS() {
InitInterRefiningTest refiningTest = new InitInterRefiningTest();
refiningTest.initRefiningTest();
final SensorPixel realPixelA = new SensorPixel(2005.015883575199, 18004.968656395424);
final SensorPixel realPixelB = new SensorPixel(4798.487736488162, 13952.2195710654);
double[] distancesBetweenLOS = refiningTest.computeDistancesBetweenLOS(realPixelA, realPixelB);
double expectedDistanceBetweenLOS = 3.88800245;
double expectedDistanceToTheGround = 6368020.559109;
Assert.assertEquals(expectedDistanceBetweenLOS, distancesBetweenLOS[0], 1.e-8);
Assert.assertEquals(expectedDistanceToTheGround, distancesBetweenLOS[1], 1.e-5);
}
@Test
public void testDistanceBetweenLOSDerivatives() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
InitInterRefiningTest refiningTest = new InitInterRefiningTest();
refiningTest.initRefiningTest();
final SensorPixel realPixelA = new SensorPixel(2005.015883575199, 18004.968656395424);
final SensorPixel realPixelB = new SensorPixel(4798.487736488162, 13952.2195710654);
// Expected distances between LOS and to the ground
double expectedDistanceBetweenLOS = 3.88800245;
double expectedDistanceToTheGround = 6368020.559109;
// Expected derivatives for
// minimum distance between LOS
double[] expectedDminDerivatives = {-153874.01319097, -678866.03112033, 191294.06938169, 668600.16715270} ;
// minimum distance to the ground
double[] expectedDcentralBodyDerivatives = {7007767.46926062, -1577060.82402054, -6839286.39593802, 1956452.66636262};
Gradient[] distancesBetweenLOSGradient = refiningTest.computeDistancesBetweenLOSGradient(realPixelA, realPixelB, expectedDistanceBetweenLOS, expectedDistanceToTheGround);
// Minimum distance between LOS
Gradient dMin = distancesBetweenLOSGradient[0];
// Minimum distance to the ground
Gradient dCentralBody = distancesBetweenLOSGradient[1];
Assert.assertEquals(expectedDistanceBetweenLOS, dMin.getValue(), 1.e-8);
Assert.assertEquals(expectedDistanceToTheGround, dCentralBody.getValue() , 1.e-5);
for (int i = 0; i < dMin.getFreeParameters(); i++) {
Assert.assertEquals(expectedDminDerivatives[i], dMin.getPartialDerivative(i), 1.e-8);
}
for (int i = 0; i < dCentralBody.getFreeParameters(); i++) {
Assert.assertEquals(expectedDcentralBodyDerivatives[i], dCentralBody.getPartialDerivative(i), 3.e-8);
}
}
@Test
public void testForCoverage() throws URISyntaxException {
int dimension = 400;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-07T11:21:15.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, centered at +Z, ±10° aperture, 960 pixels
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(Vector3D.PLUS_K, Vector3D.PLUS_I,
FastMath.toRadians(10.0), dimension).build();
// linear datation model: at reference time we get line 200, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
RuggedBuilder builder = new RuggedBuilder().
setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
setEllipsoid(EllipsoidId.IERS2003, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor);
Rugged rugged = builder.build();
// Check builder
assertTrue(builder.getName().equalsIgnoreCase("Rugged"));
// Check a date in the range of minDate - maxDate
AbsoluteDate midddleDate = lineSensor.getDate((firstLine+lastLine)/2.);
assertTrue(rugged.isInRange(midddleDate));
// Get the algorithm
assertTrue(rugged.getAlgorithm().getClass().isInstance(new IgnoreDEMAlgorithm()));
// Get the algorithm Id
assertEquals(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID, rugged.getAlgorithmId());
// Change the min and max line in inverse location to update the SensorMeanPlaneCrossing when the planeCrossing is not null
int minLine = firstLine;
int maxLine = lastLine;
double line = (firstLine + lastLine)/2.;
double pixel = dimension/2.;
AbsoluteDate date = lineSensor.getDate(line);
Vector3D pixelLos = lineSensor.getLOS(date, pixel);
GeodeticPoint gp = rugged.directLocation(date, position, pixelLos);
SensorPixel sp = rugged.inverseLocation("line", gp, minLine, maxLine);
int minLineNew = minLine + 10;
int maxLineNew = maxLine - 10;
SensorPixel spChangeLines = rugged.inverseLocation("line", gp, minLineNew, maxLineNew);
assertEquals(sp.getPixelNumber(), spChangeLines.getPixelNumber(), 1.e-9);
assertEquals(sp.getLineNumber(), spChangeLines.getLineNumber(), 1.e-9);
// For computeInverseLocOnGridWithoutAtmosphere special cases
try {
java.lang.reflect.Method computeWithoutAtmosphere =
rugged.getClass().getDeclaredMethod("computeInverseLocOnGridWithoutAtmosphere",
GeodeticPoint[][].class,
Integer.TYPE, Integer.TYPE,
LineSensor.class, Integer.TYPE, Integer.TYPE);
computeWithoutAtmosphere.setAccessible(true);
final int nbPixelGrid = 2;
final int nbLineGrid = 2;
GeodeticPoint[][] groundGridWithAtmosphere = new GeodeticPoint[nbPixelGrid][nbLineGrid];
for (int i = 0; i < nbPixelGrid; i++) {
for (int j = 0; j < nbLineGrid; j++) {
groundGridWithAtmosphere[i][j] = null;
}
}
SensorPixel[][] spNull = (SensorPixel[][]) computeWithoutAtmosphere.invoke(rugged, groundGridWithAtmosphere, nbPixelGrid, nbLineGrid, lineSensor, minLine, maxLine);
for (int i = 0; i < nbPixelGrid; i++) {
for (int j = 0; j < nbLineGrid; j++) {
assertNull(spNull[i][j]);
}
}
} catch (NoSuchMethodException | SecurityException |
IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
Assert.fail(e.getLocalizedMessage());
}
}
@Before
public void setUp() throws URISyntaxException {
TestUtils.clearFactories();
}
}
/* Copyright 2002-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.duvenhage;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.junit.Test;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.errors.OrekitException;
import org.orekit.rugged.api.RuggedException;
import org.orekit.rugged.core.AbstractAlgorithmTest;
import org.orekit.rugged.core.raster.IntersectionAlgorithm;
public class DuvenhageAlgorithmTest extends AbstractAlgorithmTest {
protected IntersectionAlgorithm createAlgorithm() {
return new DuvenhageAlgorithm();
}
@Test
public void testNumericalIssueAtTileExit() throws RuggedException, OrekitException {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm();
algorithm.setUpTilesManagement(updater, 8);
Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098);
Vector3D los = new Vector3D( 0.5127552821932051, -0.8254313129088879, -0.2361041470463311);
GeodeticPoint intersection = algorithm.intersection(earth, position, los);
checkIntersection(position, los, intersection);
}
@Test
public void testCrossingBeforeLineSegmentStart() throws RuggedException, OrekitException {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm();
algorithm.setUpTilesManagement(updater, 8);
Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098);
Vector3D los = new Vector3D( 0.42804005978915904, -0.8670291034054828, -0.2550338037664377);
GeodeticPoint intersection = algorithm.intersection(earth, position, los);
checkIntersection(position, los, intersection);
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.errors;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.RotationConvention;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.orekit.bodies.BodyShape;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.orbits.Orbit;
import org.orekit.rugged.TestUtils;
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.Rugged;
import org.orekit.rugged.api.RuggedBuilder;
import org.orekit.rugged.linesensor.LineDatation;
import org.orekit.rugged.linesensor.LineSensor;
import org.orekit.rugged.linesensor.LinearLineDatation;
import org.orekit.rugged.linesensor.SensorPixel;
import org.orekit.rugged.los.TimeDependentLOS;
import org.orekit.rugged.raster.RandomLandscapeUpdater;
import org.orekit.rugged.raster.TileUpdater;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.AngularDerivativesFilter;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.Constants;
public class DumpManagerTest {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testDump() throws URISyntaxException, IOException {
File dump = tempFolder.newFile();
DumpManager.activate(dump);
variousRuggedCalls();
DumpManager.deactivate();
int countAlgorithm = 0;
int countEllipsoid = 0;
int countDirectLoc = 0;
int countDirectLocResult = 0;
int countSpan = 0;
int countTransform = 0;
int countDEMTile = 0;
int countDEMCell = 0;
int countInverseLoc = 0;
int countInverseLocResult = 0;
int countSensor = 0;
int countSensorMeanPlane = 0;
int countSensorLOS = 0;
int countSensorDatation = 0;
int countSensorRate = 0;
try (final FileReader fr = new FileReader(dump);
final BufferedReader br = new BufferedReader(fr)) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
String trimmed = line.trim();
if (trimmed.length() > 0 && !trimmed.startsWith("#")){
if (trimmed.startsWith("algorithm:")) {
++countAlgorithm;
} else if (trimmed.startsWith("ellipsoid:")) {
++countEllipsoid;
} else if (trimmed.startsWith("direct location:")) {
++countDirectLoc;
} else if (trimmed.startsWith("direct location result:")) {
++countDirectLocResult;
} else if (trimmed.startsWith("span:")) {
++countSpan;
} else if (trimmed.startsWith("transform:")) {
++countTransform;
} else if (trimmed.startsWith("DEM tile:")) {
++countDEMTile;
} else if (trimmed.startsWith("DEM cell:")) {
++countDEMCell;
} else if (trimmed.startsWith("inverse location:")) {
++countInverseLoc;
} else if (trimmed.startsWith("inverse location result:")) {
++countInverseLocResult;
} else if (trimmed.startsWith("sensor:")) {
++countSensor;
} else if (trimmed.startsWith("sensor mean plane:")) {
++countSensorMeanPlane;
} else if (trimmed.startsWith("sensor LOS:")) {
++countSensorLOS;
} else if (trimmed.startsWith("sensor datation:")) {
++countSensorDatation;
} else if (trimmed.startsWith("sensor rate:")) {
++countSensorRate;
} else {
Assert.fail(line);
}
}
}
}
Assert.assertEquals(1, countAlgorithm);
Assert.assertEquals(1, countEllipsoid);
Assert.assertEquals(400, countDirectLoc);
Assert.assertEquals(400, countDirectLocResult);
Assert.assertEquals(1, countSpan);
Assert.assertEquals(2, countTransform);
Assert.assertEquals(2, countDEMTile);
Assert.assertEquals(812, countDEMCell);
Assert.assertEquals(5, countInverseLoc);
Assert.assertEquals(5, countInverseLocResult);
Assert.assertEquals(1, countSensor);
Assert.assertEquals(1, countSensorMeanPlane);
Assert.assertEquals(422, countSensorLOS);
Assert.assertEquals(19, countSensorDatation);
Assert.assertEquals(6, countSensorRate);
}
public void variousRuggedCalls()
throws URISyntaxException {
int dimension = 200;
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
final BodyShape earth = TestUtils.createEarth();
final Orbit orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
// one line sensor
// position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
// los: swath in the (YZ) plane, looking at 50° roll, ±1° aperture
Vector3D position = new Vector3D(1.5, 0, -0.2);
TimeDependentLOS los = TestUtils.createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
FastMath.toRadians(50.0),
RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension).build();
// linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
int firstLine = 0;
int lastLine = dimension;
LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
AbsoluteDate minDate = lineSensor.getDate(firstLine);
AbsoluteDate maxDate = lineSensor.getDate(lastLine);
TileUpdater updater =
new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
FastMath.toRadians(1.0), 257);
Rugged rugged = new RuggedBuilder().
setDigitalElevationModel(updater, 8).
setAlgorithm(AlgorithmId.DUVENHAGE).
setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
setTimeSpan(minDate, maxDate, 0.001, 5.0).
setTrajectory(InertialFrameId.EME2000,
TestUtils.orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
8, CartesianDerivativesFilter.USE_PV,
TestUtils.orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
2, AngularDerivativesFilter.USE_R).
addLineSensor(lineSensor).build();
GeodeticPoint[] gpLine = rugged.directLocation("line", 100);
for (int i = 0; i < gpLine.length; ++i) {
GeodeticPoint gpPixel =
rugged.directLocation(lineSensor.getDate(100), lineSensor.getPosition(),
lineSensor.getLOS(lineSensor.getDate(100), i));
Assert.assertEquals(gpLine[i].getLatitude(), gpPixel.getLatitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getLongitude(), gpPixel.getLongitude(), 1.0e-10);
Assert.assertEquals(gpLine[i].getAltitude(), gpPixel.getAltitude(), 1.0e-10);
if (i % 45 == 0) {
SensorPixel sp = rugged.inverseLocation(lineSensor.getName(), gpPixel, 0, 179);
Assert.assertEquals(100, sp.getLineNumber(), 1.0e-5);
Assert.assertEquals(i, sp.getPixelNumber(), 6.0e-9);
}
}
}
@Test
public void testAlreadyActive() throws URISyntaxException, IOException {
DumpManager.activate(tempFolder.newFile());
try {
DumpManager.activate(tempFolder.newFile());
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.DEBUG_DUMP_ALREADY_ACTIVE, re.getSpecifier());
} finally {
DumpManager.deactivate();
}
}
@Test
public void testNotActive() throws URISyntaxException, IOException {
try {
DumpManager.deactivate();
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.DEBUG_DUMP_NOT_ACTIVE, re.getSpecifier());
}
}
@Test
public void testWriteError() throws URISyntaxException, IOException {
try {
DumpManager.activate(tempFolder.getRoot());
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.DEBUG_DUMP_ACTIVATION_ERROR, re.getSpecifier());
}
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.errors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.hipparchus.analysis.differentiation.DSFactory;
import org.hipparchus.analysis.differentiation.DerivativeStructure;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.rugged.api.Rugged;
import org.orekit.rugged.linesensor.SensorPixel;
import org.orekit.rugged.refraction.MultiLayerModel;
import org.orekit.rugged.utils.DerivativeGenerator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.ParameterDriver;
public class DumpReplayerTest {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testDirectLoc01() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-01.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
Assert.assertEquals(5, results.length);
for (final DumpReplayer.Result result : results) {
GeodeticPoint expectedGP = (GeodeticPoint) result.getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) result.getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 6.0e-8);
}
}
@Test
public void testDirectLoc02() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-02.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
Assert.assertEquals(1, results.length);
for (final DumpReplayer.Result result : results) {
GeodeticPoint expectedGP = (GeodeticPoint) result.getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) result.getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 1.0e-8);
}
}
@Test
public void testDirectLoc03() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-03.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
Assert.assertEquals(1, results.length);
for (final DumpReplayer.Result result : results) {
GeodeticPoint expectedGP = (GeodeticPoint) result.getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) result.getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 1.0e-8);
}
}
@Test
public void testDirectLoc04() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-04.txt").toURI().getPath();
File dump = tempFolder.newFile();
DumpManager.activate(dump);
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
DumpManager.deactivate();
Assert.assertEquals(3, results.length);
for (final DumpReplayer.Result result : results) {
GeodeticPoint expectedGP = (GeodeticPoint) result.getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) result.getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 1.0e-8);
}
try (FileReader fr = new FileReader(dump);
BufferedReader br = new BufferedReader(fr)) {
Assert.assertEquals(12, br.lines().count());
}
}
@Test
public void testDirectLocNull() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// Create a dump file with NULL result for direct location
createDataForCreateRugged(bw);
bw.write("direct location: date 2012-01-01T12:29:30.85Z position 0.0e+00 0.0e+00 0.0e+00 " +
"los -2.2e-02 -9.1e-02 9.9e-01 lightTime false aberration false refraction false");
bw.newLine();
bw.write("direct location result: NULL");
}
DumpReplayer replayer = new DumpReplayer();
replayer.parse(tempFile);
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
assertTrue(results[0].getExpected() == null);
tempFile.delete();
}
@Test
public void testInverseLoc01() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-inverse-loc-01.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
Assert.assertEquals(1, results.length);
for (final DumpReplayer.Result result : results) {
SensorPixel expectedSP = (SensorPixel) result.getExpected();
SensorPixel replayedSP = (SensorPixel) result.getReplayed();
Assert.assertEquals(expectedSP.getLineNumber(), replayedSP.getLineNumber(), 1.0e-6);
Assert.assertEquals(expectedSP.getPixelNumber(), replayedSP.getPixelNumber(), 1.0e-6);
}
}
@Test
public void testInverseLoc02() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-inverse-loc-02.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
Assert.assertEquals(3, results.length);
for (final DumpReplayer.Result result : results) {
SensorPixel expectedSP = (SensorPixel) result.getExpected();
SensorPixel replayedSP = (SensorPixel) result.getReplayed();
Assert.assertEquals(expectedSP.getLineNumber(), replayedSP.getLineNumber(), 1.0e-6);
Assert.assertEquals(expectedSP.getPixelNumber(), replayedSP.getPixelNumber(), 1.0e-6);
}
}
@Test
public void testInverseLoc03() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-inverse-loc-03.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
Assert.assertEquals(1, results.length);
for (final DumpReplayer.Result result : results) {
SensorPixel expectedSP = (SensorPixel) result.getExpected();
SensorPixel replayedSP = (SensorPixel) result.getReplayed();
Assert.assertEquals(expectedSP.getLineNumber(), replayedSP.getLineNumber(), 1.0e-6);
Assert.assertEquals(expectedSP.getPixelNumber(), replayedSP.getPixelNumber(), 1.0e-6);
}
}
@Test
public void testInverseLocNull() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// Create a dump file with NULL result for inverse location
createDataForInvLocResult(bw);
bw.write("inverse location result: NULL");
}
DumpReplayer replayer = new DumpReplayer();
replayer.parse(tempFile);
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
assertTrue(results[0].getExpected() == null);
tempFile.delete();
}
@Test
public void testCorruptedFiles() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File folder = new File(getClass().getClassLoader().getResource("replay/replay-direct-loc-01.txt").toURI().getPath()).getParentFile();
for (final File file : folder.listFiles()) {
// split all data lines into fields
final List<String[]> lines = new ArrayList<>();
try (FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
br.lines().
filter(line -> {
String trimmed = line.trim();
return trimmed.length() > 0 && !trimmed.startsWith("#");
}).
forEach(line -> lines.add(line.split("\\s+")));
}
// for each field of each line, delete the field and check parsing fails
for (int i = 0; i < lines.size(); ++i) {
for (int j = 0; j < lines.get(i).length; ++j) {
final File corrupted = tempFolder.newFile();
try (PrintWriter pw = new PrintWriter(corrupted, "UTF-8")) {
for (int k = 0; k < lines.size(); ++k) {
for (int l = 0; l < lines.get(k).length; ++l) {
if (k != i || l != j) {
pw.print(' ');
pw.print(lines.get(k)[l]);
}
}
pw.println();
}
}
try {
new DumpReplayer().parse(corrupted);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.CANNOT_PARSE_LINE, re.getSpecifier());
Assert.assertEquals(i + 1, ((Integer) re.getParts()[0]).intValue());
Assert.assertEquals(corrupted, re.getParts()[1]);
}
corrupted.delete();
}
}
}
}
@Test
public void testDirectLocIssue376_01() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-Issue376-01.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
GeodeticPoint expectedGP = (GeodeticPoint) results[0].getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) results[0].getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 1.0e-8);
}
@Test
public void testDirectLocIssue376_02() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-Issue376-02.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
GeodeticPoint expectedGP = (GeodeticPoint) results[0].getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) results[0].getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 1.0e-8);
}
@Test
public void testDirectLocIssue376_03() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-direct-loc-Issue376-03.txt").toURI().getPath();
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
DumpReplayer.Result[] results = replayer.execute(rugged);
for (int i= 0; i < results.length; i++) {
GeodeticPoint expectedGP = (GeodeticPoint) results[i].getExpected();
GeodeticPoint replayedGP = (GeodeticPoint) results[i].getReplayed();
double distance = Vector3D.distance(rugged.getEllipsoid().transform(expectedGP),
rugged.getEllipsoid().transform(replayedGP));
Assert.assertEquals(0.0, distance, 5.0e-8);
}
}
@Test
public void testCreateRuggedWithAtmosphere() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// CreateRugged with atmospheric refraction
bw.write("direct location: date 2012-01-01T12:30:00.0Z position 1.5e+00 0.e+00 -2.e-01 "+
"los 0.e+00 -7.5e-01 6.5e-01 lightTime true aberration true refraction true");
bw.newLine();
createDataForCreateRugged(bw);
}
DumpReplayer replayer = new DumpReplayer();
replayer.parse(tempFile);
Rugged rugged = replayer.createRugged();
assertTrue(rugged.getRefractionCorrection().getClass().isInstance(new MultiLayerModel(rugged.getEllipsoid())));
tempFile.delete();
}
@Test
public void testCreateRuggedNoDEMdata() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// CreateRugged with atmospheric refraction
bw.write("direct location: date 2012-01-01T12:30:00.0Z position 1.5e+00 0.e+00 -2.e-01 "+
"los 0.e+00 -7.5e-01 6.5e-01 lightTime true aberration true refraction false");
bw.newLine();
createDataForCreateRugged(bw);
bw.write("algorithm: DUVENHAGE");
}
DumpReplayer replayer = new DumpReplayer();
replayer.parse(tempFile);
Rugged rugged = replayer.createRugged();
try {
replayer.execute(rugged);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
// as the execution stops in the TilesCache: one must reset the DumpManager state
DumpManager.endNicely();
Assert.assertEquals(RuggedMessages.NO_DEM_DATA, re.getSpecifier());
}
tempFile.delete();
}
@Test
public void testLineParserBadKey() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// this empty line to ensure coverage
bw.write("");
bw.newLine();
// LineParser.parse: case bad key
bw.write("dummy : dummy");
}
DumpReplayer replayer = new DumpReplayer();
try {
replayer.parse(tempFile);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.CANNOT_PARSE_LINE, re.getSpecifier());
Assert.assertEquals(2, ((Integer) re.getParts()[0]).intValue());
Assert.assertEquals(tempFile, re.getParts()[1]);
Assert.assertTrue(re.getParts()[2].toString().contains("dummy : dummy"));
}
tempFile.delete();
}
@Test
public void testLineParserEndColon() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// LineParser.parse: case colon at end of line
bw.write("direct location result:");
}
DumpReplayer replayer = new DumpReplayer();
try {
replayer.parse(tempFile);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.CANNOT_PARSE_LINE, re.getSpecifier());
Assert.assertEquals(1, ((Integer) re.getParts()[0]).intValue());
Assert.assertEquals(tempFile, re.getParts()[1]);
}
tempFile.delete();
}
@Test
public void testLineParserNoColon() throws URISyntaxException, IOException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
File tempFile = tempFolder.newFile();
try (FileOutputStream fos = new FileOutputStream(tempFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw)) {
// LineParser.parse case no colon
bw.write("sensorName s0 nbPixels 200 position 1.5e+00 0.0e+00 -2.0e-01");
}
DumpReplayer replayer = new DumpReplayer();
try {
replayer.parse(tempFile);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.CANNOT_PARSE_LINE, re.getSpecifier());
Assert.assertEquals(1, ((Integer) re.getParts()[0]).intValue());
Assert.assertEquals(tempFile, re.getParts()[1]);
}
tempFile.delete();
}
@Test
public void testParsedSensorGetDateGetLineCoverage() throws URISyntaxException, ClassNotFoundException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
// ParsedSensor inner class
Class<?> innerClass = Class.forName("org.orekit.rugged.errors.DumpReplayer$ParsedSensor");
Constructor<?>[] constructors = innerClass.getDeclaredConstructors();
constructors[0].setAccessible(true);
Object parsedSensor = constructors[0].newInstance("dummy");
Method getLine = innerClass.getDeclaredMethod("getLine", AbsoluteDate.class);
getLine.setAccessible(true);
Method getDate = innerClass.getDeclaredMethod("getDate", double.class);
getDate.setAccessible(true);
Method setDatation = innerClass.getDeclaredMethod("setDatation", double.class, AbsoluteDate.class);
setDatation.setAccessible(true);
// datation with only one data
AbsoluteDate date0 = new AbsoluteDate("2012-01-06T02:27:16.139", TimeScalesFactory.getUTC());
setDatation.invoke(parsedSensor, 100., date0);
AbsoluteDate date = date0.shiftedBy(5.);
double foundLine = (double) getLine.invoke(parsedSensor, date);
assertEquals(100., foundLine, 1.e-15);
double line = 105.;
AbsoluteDate foundDate = (AbsoluteDate) getDate.invoke(parsedSensor, line);
assertEquals("2012-01-06T02:27:16.139",foundDate.toString(TimeScalesFactory.getUTC()));
// add datations data
AbsoluteDate date1 = date0.shiftedBy(10.);
AbsoluteDate date2 = date1.shiftedBy(10.);
setDatation.invoke(parsedSensor, 120., date1);
setDatation.invoke(parsedSensor, 150., date2);
foundLine = (double) getLine.invoke(parsedSensor, date);
assertEquals(110., foundLine, 1.e-15);
date = date2.shiftedBy(5.);
foundLine = (double) getLine.invoke(parsedSensor, date);
assertEquals(165., foundLine, 1.e-15);
date = date0.shiftedBy(-5.);
foundLine = (double) getLine.invoke(parsedSensor, date);
assertEquals(90., foundLine, 1.e-15);
}
@Test
public void testParsedSensorGetLOSCoverage() throws URISyntaxException, ClassNotFoundException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
// ParsedSensor inner class
Class<?> innerClass = Class.forName("org.orekit.rugged.errors.DumpReplayer$ParsedSensor");
Constructor<?>[] constructors = innerClass.getDeclaredConstructors();
constructors[0].setAccessible(true);
Object parsedSensor = constructors[0].newInstance("dummy");
AbsoluteDate date = new AbsoluteDate("2012-01-06T02:27:16.139", TimeScalesFactory.getUTC());
// ParsedSensor.getLOS RunTimeException
Method getLos = innerClass.getDeclaredMethod("getLOS", int.class, AbsoluteDate.class);
getLos.setAccessible(true);
try {
getLos.invoke(parsedSensor, 1, date);
Assert.fail("an exception should have been thrown");
} catch (InvocationTargetException ite) {
RuggedInternalError rie = (RuggedInternalError) ite.getTargetException();
assertEquals(RuggedMessages.INTERNAL_ERROR, rie.getSpecifier());
assertEquals("https://gitlab.orekit.org/orekit/rugged/issues", rie.getParts()[0]);
assertTrue(rie.getMessage(Locale.FRENCH).startsWith("erreur interne"));
}
}
@Test
public void testParsedSensorLOSCoverage() throws URISyntaxException, ClassNotFoundException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
// ParsedSensor inner class
Class<?> innerClass = Class.forName("org.orekit.rugged.errors.DumpReplayer$ParsedSensor");
Constructor<?>[] constructors = innerClass.getDeclaredConstructors();
constructors[0].setAccessible(true);
Object parsedSensor = constructors[0].newInstance("dummy");
AbsoluteDate date0 = new AbsoluteDate("2012-01-06T02:27:16.139", TimeScalesFactory.getUTC());
AbsoluteDate date = date0.shiftedBy(5.);
AbsoluteDate date1 = date0.shiftedBy(10.);
AbsoluteDate date2 = date1.shiftedBy(10.);
// ParsedSensor.setLos
Method setLos = innerClass.getDeclaredMethod("setLOS", AbsoluteDate.class, int.class, Vector3D.class);
setLos.setAccessible(true);
setLos.invoke(parsedSensor, date, 1, new Vector3D(0, 0, 0));
setLos.invoke(parsedSensor, date1, 100, new Vector3D(1, 1, 1));
setLos.invoke(parsedSensor, date2, 200, new Vector3D(2, 2, 2));
setLos.invoke(parsedSensor, date2.shiftedBy(10.), 200, new Vector3D(3, 3, 3));
// ParsedSensor.getLOSDerivatives
// Needs some LOS to be set
Method getLOSDerivatives = innerClass.getDeclaredMethod("getLOSDerivatives", int.class, AbsoluteDate.class, DerivativeGenerator.class);
getLOSDerivatives.setAccessible(true);
final DSFactory factory = new DSFactory(1, 1);
DerivativeGenerator<DerivativeStructure> generator = new DerivativeGenerator<DerivativeStructure>() {
@Override
public List<ParameterDriver> getSelected() {
return null;
}
@Override
public DerivativeStructure constant(final double value) {
return factory.constant(value);
}
@Override
public DerivativeStructure variable(final ParameterDriver driver) {
return null;
}
};
@SuppressWarnings("unchecked")
FieldVector3D<DerivativeStructure> fv= (FieldVector3D<DerivativeStructure>) getLOSDerivatives.invoke(parsedSensor, 1, date, generator);
assertEquals(0., fv.getX().getValue(), 1.e-15);
assertEquals(0., fv.getY().getValue(), 1.e-15);
assertEquals(0., fv.getZ().getValue(), 1.e-15);
// ParsedSensor.getParametersDrivers
Method getParametersDrivers = innerClass.getDeclaredMethod("getParametersDrivers");
getParametersDrivers.setAccessible(true);
getParametersDrivers.invoke(parsedSensor);
}
private void createDataForCreateRugged(BufferedWriter bw) throws IOException {
bw.write("ellipsoid: ae 6.378137e+06 f 3.35e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP");
bw.newLine();
bw.write("span: minDate 2012-01-01T12:29:00.85Z maxDate 2012-01-01T12:30:00.15Z " +
"tStep 1.e-03 tolerance 5.e+00 inertialFrame EME2000");
bw.newLine();
bw.write("transform: index 150 body r -8.0e-01 -3.4e-04 4.8e-04 -5.8e-01 Ω -8.7e-08 1.2e-09 -7.3e-05 " +
"ΩDot -1.6e-16 8.9e-17 1.9e-19 spacecraft p 1.3e+04 3.1e+03 -7.1e+06 v -3.1e+01 -8.0e+00 8.2e+00 " +
"a -9.3e-01 -8.3e+00 1.3e-03 r -6.8e-01 4.1e-01 -3.8e-01 4.6e-01 Ω -1.e-03 1.9e-04 1.6e-04 " +
"ΩDot -3.6e-07 2.0e-07 -1.2e-06");
bw.newLine();
}
private void createDataForInvLocResult(BufferedWriter bw) throws IOException {
bw.write("inverse location: sensorName s0 latitude 1.4e+00 longitude -8.8e-01 elevation 3.1e+01 minLine -23040 maxLine 39851 " +
"lightTime false aberration false refraction false");
bw.newLine();
bw.write("ellipsoid: ae 6.378e+06 f 3.35e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP");
bw.newLine();
bw.write("span: minDate 2015-07-07T18:38:55.0Z maxDate 2015-07-07T18:40:35.8Z tStep 1.e-01 tolerance 1.e+01 inertialFrame EME2000");
bw.newLine();
bw.write("transform: index 516 body r -2.2e-01 -7.3e-04 1.8e-04 -9.7e-01 Ω -1.1e-07 3.6e-09 -7.2e-05 " +
"ΩDot 0. 0. 0. spacecraft p -3.6e+02 -4.2e+02 -7.1e+06 v -7.4e+01 -3.4e+02 -1.8e-01 " +
"a 0. 0. 0. r -6.2e-02 7.4e-01 6.5e-01 4.1e-02 Ω 0. 0. 0. " +
"ΩDot 0. 0. 0.");
bw.newLine();
bw.write("sensor: sensorName s0 nbPixels 2552 position 0. 0. 0.");
bw.newLine();
bw.write("sensor mean plane: sensorName s0 minLine -23040 maxLine 39851 maxEval 50 accuracy 1.e-02 " +
"normal 9.e-01 -2.6e-02 1.8e-02 cachedResults 1 lineNumber 2.4e+04 date 2015-07-07T18:40:12.4Z " +
"target 5.8e+05 -7.1e+05 6.2e+06 targetDirection -1.5e-02 8.9e-02 9.9e-01 -2.0e-07 2.1e-08 -2.0e-07");
bw.newLine();
bw.write("sensor datation: sensorName s0 lineNumber 8.4e+03 date 2015-07-07T18:39:46.5Z");
bw.newLine();
bw.write("sensor rate: sensorName s0 lineNumber 2.4e+04 rate 6.3e+02");
bw.newLine();
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.errors;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.frames.Transform;
import org.orekit.rugged.api.Rugged;
import org.orekit.rugged.linesensor.SensorPixel;
public class DumpTest {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testGetKeyOrNameCoverage() throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, IOException {
File tempFile = tempFolder.newFile();
PrintWriter pw = new PrintWriter(tempFile, "UTF-8");
Dump dump = new Dump(pw);
Method getKeyOrName = dump.getClass().getDeclaredMethod("getKeyOrName", Frame.class);
getKeyOrName.setAccessible(true);
String dummyName = "dummy";
Frame frame = new Frame(FramesFactory.getEME2000(), Transform.IDENTITY, dummyName);
String foundName = (String) getKeyOrName.invoke(dump, frame);
assertTrue(foundName.equals(dummyName));
}
@Test
public void testInverseLocNull() throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, IOException {
File tempFile = tempFolder.newFile();
PrintWriter pw = new PrintWriter(tempFile, "UTF-8");
Dump dump = new Dump(pw);
Method dumpInverseLocationResult = dump.getClass().getDeclaredMethod("dumpInverseLocationResult", SensorPixel.class);
dumpInverseLocationResult.setAccessible(true);
SensorPixel px = null;
// just to ensure the test coverage
dumpInverseLocationResult.invoke(dump, px);
dump.deactivate();
// Check that the created file contains the line "inverse location result: NULL"
try (FileInputStream fis = new FileInputStream(tempFile);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
final String trimmed = line.trim();
if (!(trimmed.length() == 0 || trimmed.startsWith("#"))) {
assertTrue(line.contains("inverse location result: NULL"));
}
}
}
}
@Test
public void testDirectLocNull() throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, IOException {
File tempFile = tempFolder.newFile();
PrintWriter pw = new PrintWriter(tempFile, "UTF-8");
Dump dump = new Dump(pw);
Method dumpDirectLocationResult = dump.getClass().getDeclaredMethod("dumpDirectLocationResult", GeodeticPoint.class);
dumpDirectLocationResult.setAccessible(true);
GeodeticPoint gp = null;
// just to ensure the coverage
dumpDirectLocationResult.invoke(dump, gp);
dump.deactivate();
// Check that the created file contains the line "inverse location result: NULL"
try (FileInputStream fis = new FileInputStream(tempFile);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
final String trimmed = line.trim();
if (!(trimmed.length() == 0 || trimmed.startsWith("#"))) {
assertTrue(line.contains("direct location result: NULL"));
}
}
}
}
@Test
public void testSetMeanPlane() throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, IOException, URISyntaxException {
String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(orekitPath)));
String dumpPath = getClass().getClassLoader().getResource("replay/replay-inverse-loc-02.txt").toURI().getPath();
// Regenerate a dump in order to write the "sensor mean plane: sensorName xxx lineNumber xxx targetDirection xxx targetDirection xxx ...."
File dummyDump = tempFolder.newFile();
DumpManager.activate(dummyDump);
DumpReplayer replayer = new DumpReplayer();
replayer.parse(new File(dumpPath));
Rugged rugged = replayer.createRugged();
replayer.execute(rugged);
DumpManager.deactivate();
// Check that the created dump contains the line " lineNumber xxx targetDirection xxx targetDirection xxx ...."
try (FileInputStream fis = new FileInputStream(dummyDump);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
final String trimmed = line.trim();
if (!(trimmed.length() == 0 || trimmed.startsWith("#"))) {
if (line.contains("lineNumber ")&& line.contains("targetDirection ")) {
assertTrue(line.split("targetDirection").length == 6);
}
}
}
}
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.errors;
import java.util.Locale;
import org.junit.Assert;
import org.junit.Test;
public class RuggedExceptionTest {
@Test
public void testTranslation() {
RuggedException re = new RuggedException(RuggedMessages.DUPLICATED_PARAMETER_NAME, "dummy");
Assert.assertFalse(re.getMessage(Locale.FRENCH).contains("parameter"));
Assert.assertTrue(re.getMessage(Locale.FRENCH).contains("paramètre"));
Assert.assertTrue(re.getMessage(Locale.FRENCH).contains("dummy"));
Assert.assertTrue(re.getMessage(Locale.US).contains("parameter"));
Assert.assertFalse(re.getMessage(Locale.US).contains("paramètre"));
Assert.assertTrue(re.getMessage(Locale.US).contains("dummy"));
Assert.assertEquals(re.getMessage(), re.getMessage(Locale.US));
}
@Test
public void testParameters() {
RuggedException re = new RuggedException(RuggedMessages.DUPLICATED_PARAMETER_NAME, "dummy");
Assert.assertEquals(RuggedMessages.DUPLICATED_PARAMETER_NAME, re.getSpecifier());
Assert.assertEquals("dummy", re.getParts()[0]);
}
@Test
public void testNullSpecifier() {
RuggedException re = new RuggedException(null, (Object[]) null);
Assert.assertEquals("", re.getMessage());
}
@Test
public void testNullParts() {
RuggedException re1 = new RuggedException(RuggedMessages.NO_PARAMETERS_SELECTED, (Object[]) null);
Assert.assertEquals(RuggedMessages.NO_PARAMETERS_SELECTED, re1.getSpecifier());
Assert.assertEquals(0, re1.getParts().length);
RuggedException re2 = new RuggedException(new RuntimeException(),
RuggedMessages.NO_PARAMETERS_SELECTED, (Object[]) null);
Assert.assertEquals(RuggedMessages.NO_PARAMETERS_SELECTED, re2.getSpecifier());
Assert.assertEquals(0, re2.getParts().length);
}
@Test
public void testInternalError() {
RuggedException re = new RuggedException(RuggedMessages.DUPLICATED_PARAMETER_NAME, "dummy");
RuntimeException rte = new RuggedInternalError(re);
Assert.assertFalse(re.getLocalizedMessage().contains("https://gitlab.orekit.org/orekit/rugged/issues"));
Assert.assertTrue(rte.getLocalizedMessage().contains("https://gitlab.orekit.org/orekit/rugged/issues"));
Assert.assertTrue(rte.getMessage().contains("https://gitlab.orekit.org/orekit/rugged/issues"));
}
@Deprecated
@Test
public void testCoverage() {
RuggedExceptionWrapper rew = new RuggedExceptionWrapper(new RuggedException(RuggedMessages.DUPLICATED_PARAMETER_NAME, "dummy"));
RuggedException re = rew.getException();
Assert.assertEquals(RuggedMessages.DUPLICATED_PARAMETER_NAME, re.getSpecifier());
Assert.assertEquals("dummy", re.getParts()[0]);
}
}
/* Copyright 2002-2014 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.rugged.api;
package org.orekit.rugged.errors;
import java.text.MessageFormat;
......@@ -27,17 +27,18 @@ import org.junit.Test;
public class RuggedMessagesTest {
private final String[] LANGUAGES_LIST = { "da", "de", "en", "es", "fr", "gl", "it", "no", "ro" } ;
@Test
public void testMessageNumber() {
Assert.assertEquals(10, RuggedMessages.values().length);
Assert.assertEquals(35, RuggedMessages.values().length);
}
@Test
public void testAllKeysPresentInPropertiesFiles() {
for (final String language : new String[] { "en", "fr" } ) {
for (final String language : LANGUAGES_LIST) {
ResourceBundle bundle =
ResourceBundle.getBundle("assets/org/orekit/rugged/RuggedMessages",
new Locale(language), new RuggedMessages.UTF8Control());
ResourceBundle.getBundle("assets/org/orekit/rugged/RuggedMessages",
new Locale(language), new RuggedMessages.UTF8Control());
for (RuggedMessages message : RuggedMessages.values()) {
final String messageKey = message.toString();
boolean keyPresent = false;
......@@ -54,10 +55,10 @@ public class RuggedMessagesTest {
@Test
public void testAllPropertiesCorrespondToKeys() {
for (final String language : new String[] { "en", "fr" } ) {
for (final String language : LANGUAGES_LIST) {
ResourceBundle bundle =
ResourceBundle.getBundle("assets/org/orekit/rugged/RuggedMessages",
new Locale(language), new RuggedMessages.UTF8Control());
ResourceBundle.getBundle("assets/org/orekit/rugged/RuggedMessages",
new Locale(language), new RuggedMessages.UTF8Control());
for (final Enumeration<String> keys = bundle.getKeys(); keys.hasMoreElements();) {
final String propertyKey = keys.nextElement();
try {
......@@ -87,9 +88,29 @@ public class RuggedMessagesTest {
}
}
@Test
public void testMissingLanguageFallback() {
for (RuggedMessages message : RuggedMessages.values()) {
String translated = message.getLocalizedString(Locale.TRADITIONAL_CHINESE);
Assert.assertEquals(message.getSourceString(), translated);
}
}
@Test
public void testMissingLanguageMissingTranslation() {
Assert.assertEquals(RuggedMessages.INTERNAL_ERROR.getSourceString(),
RuggedMessages.INTERNAL_ERROR.getLocalizedString(Locale.KOREAN));
Assert.assertEquals(RuggedMessages.NO_DEM_DATA.getSourceString(),
RuggedMessages.NO_DEM_DATA.getLocalizedString(Locale.KOREAN));
Assert.assertEquals("ABCDEF {0}",
RuggedMessages.UNKNOWN_SENSOR.getLocalizedString(Locale.KOREAN));
Assert.assertEquals(RuggedMessages.EMPTY_TILE.getSourceString(),
RuggedMessages.EMPTY_TILE.getLocalizedString(Locale.KOREAN));
}
@Test
public void testVariablePartsConsistency() {
for (final String language : new String[] { "en", "fr" } ) {
for (final String language : LANGUAGES_LIST) {
Locale locale = new Locale(language);
for (RuggedMessages message : RuggedMessages.values()) {
MessageFormat source = new MessageFormat(message.getSourceString());
......
/* Copyright 2002-2014 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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
......@@ -14,36 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.rugged.core;
package org.orekit.rugged.intersection;
import java.io.File;
import java.net.URISyntaxException;
import org.apache.commons.math3.geometry.euclidean.threed.Line;
import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.apache.commons.math3.util.FastMath;
import org.hipparchus.geometry.euclidean.threed.Line;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.attitudes.Attitude;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.data.DataProvidersManager;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.errors.OrekitException;
import org.orekit.frames.FramesFactory;
import org.orekit.frames.Transform;
import org.orekit.orbits.CartesianOrbit;
import org.orekit.propagation.SpacecraftState;
import org.orekit.rugged.api.RuggedException;
import org.orekit.rugged.api.TileUpdater;
import org.orekit.rugged.core.duvenhage.MinMaxTreeTile;
import org.orekit.rugged.core.duvenhage.MinMaxTreeTileFactory;
import org.orekit.rugged.core.raster.CliffsElevationUpdater;
import org.orekit.rugged.core.raster.IntersectionAlgorithm;
import org.orekit.rugged.core.raster.VolcanicConeElevationUpdater;
import org.orekit.rugged.intersection.duvenhage.MinMaxTreeTile;
import org.orekit.rugged.intersection.duvenhage.MinMaxTreeTileFactory;
import org.orekit.rugged.raster.CliffsElevationUpdater;
import org.orekit.rugged.raster.TileUpdater;
import org.orekit.rugged.raster.VolcanicConeElevationUpdater;
import org.orekit.rugged.utils.ExtendedEllipsoid;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
......@@ -52,16 +50,15 @@ import org.orekit.utils.PVCoordinates;
public abstract class AbstractAlgorithmTest {
protected abstract IntersectionAlgorithm createAlgorithm();
protected abstract IntersectionAlgorithm createAlgorithm(TileUpdater updater, int maxCachedTiles);
@Test
public void testMayonVolcanoOnSubTileCorner()
throws RuggedException, OrekitException {
public void testMayonVolcanoOnSubTileCorner() {
setUpMayonVolcanoContext();
// test point approximately 1.6km North-North-West and 800 meters below volcano summit
// note that this test point is EXACTLY at a pixel corner, and even at corners of
// note that this test point is EXACTLY at a cell corner, and even at corners of
// middle level (12 and above) sub-tiles
final double latitude = FastMath.toRadians(13.27);
final double longitude = FastMath.toRadians(123.68);
......@@ -71,8 +68,7 @@ public abstract class AbstractAlgorithmTest {
final GeodeticPoint groundGP = new GeodeticPoint(latitude, longitude, altitude);
Vector3D groundP = earth.transform(groundGP);
final IntersectionAlgorithm algorithm = createAlgorithm();
algorithm.setUpTilesManagement(updater, 8);
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
// preliminary check: the point has been chosen in the spacecraft (YZ) plane
Transform earthToSpacecraft = new Transform(state.getDate(),
......@@ -83,18 +79,18 @@ public abstract class AbstractAlgorithmTest {
Assert.assertEquals(-87754.914, pointInSpacecraftFrame.getY(), 1.0e-3);
Assert.assertEquals(790330.254, pointInSpacecraftFrame.getZ(), 1.0e-3);
// test direct localization
// test direct location
Vector3D position = state.getPVCoordinates(earth.getBodyFrame()).getPosition();
Vector3D los = groundP.subtract(position);
GeodeticPoint result = algorithm.intersection(earth, position, los);
GeodeticPoint result = algorithm.refineIntersection(earth, position, los,
algorithm.intersection(earth, position, los));
checkIntersection(position, los, result);
Assert.assertEquals(0.0, groundP.distance(earth.transform(result)), 2.0e-9);
}
@Test
public void testMayonVolcanoWithinPixel()
throws RuggedException, OrekitException {
public void testMayonVolcanoWithinPixel() {
setUpMayonVolcanoContext();
......@@ -106,13 +102,13 @@ public abstract class AbstractAlgorithmTest {
final GeodeticPoint groundGP = new GeodeticPoint(latitude, longitude, altitude);
Vector3D groundP = earth.transform(groundGP);
final IntersectionAlgorithm algorithm = createAlgorithm();
algorithm.setUpTilesManagement(updater, 8);
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
// test direct localization
// test direct location
Vector3D position = state.getPVCoordinates(earth.getBodyFrame()).getPosition();
Vector3D los = groundP.subtract(position);
GeodeticPoint result = algorithm.intersection(earth, position, los);
GeodeticPoint result = algorithm.refineIntersection(earth, position, los,
algorithm.intersection(earth, position, los));
checkIntersection(position, los, result);
Assert.assertEquals(0.0, groundP.distance(earth.transform(result)), 2.0e-9);
......@@ -120,7 +116,7 @@ public abstract class AbstractAlgorithmTest {
@Test
public void testCliffsOfMoher()
throws RuggedException, OrekitException {
{
setUpCliffsOfMoherContext();
......@@ -133,8 +129,9 @@ public abstract class AbstractAlgorithmTest {
final GeodeticPoint groundGP = new GeodeticPoint(latitude, longitude, altitude);
Vector3D groundP = earth.transform(groundGP);
final IntersectionAlgorithm algorithm = createAlgorithm();
algorithm.setUpTilesManagement(updater, 8);
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
Assert.assertEquals( 0.0, algorithm.getElevation(latitude, longitude - 2.0e-5), 1.0e-6);
Assert.assertEquals(120.0, algorithm.getElevation(latitude, longitude + 2.0e-5), 1.0e-6);
// preliminary check: the point has been chosen in the spacecraft (YZ) plane
Transform earthToSpacecraft = new Transform(state.getDate(),
......@@ -147,14 +144,14 @@ public abstract class AbstractAlgorithmTest {
Vector3D position = state.getPVCoordinates(earth.getBodyFrame()).getPosition();
Vector3D los = groundP.subtract(position);
GeodeticPoint result = algorithm.intersection(earth, position, los);
GeodeticPoint result = algorithm.refineIntersection(earth, position, los,
algorithm.intersection(earth, position, los));
checkIntersection(position, los, result);
Assert.assertEquals(0.0, groundP.distance(earth.transform(result)), 2.0e-9);
}
protected void checkIntersection(Vector3D position, Vector3D los, GeodeticPoint intersection)
throws RuggedException {
protected void checkIntersection(Vector3D position, Vector3D los, GeodeticPoint intersection) {
// check the point is on the line
Line line = new Line(position, new Vector3D(1, position, 1e6, los), 1.0e-12);
......@@ -169,7 +166,7 @@ public abstract class AbstractAlgorithmTest {
}
protected void setUpMayonVolcanoContext()
throws RuggedException, OrekitException {
{
// Mayon Volcano location according to Wikipedia: 13°15′24″N 123°41′6″E
GeodeticPoint summit =
......@@ -211,12 +208,13 @@ public abstract class AbstractAlgorithmTest {
true),
new Vector3D(-7.048568391860185e-05,
-1.043582650222194e-03,
1.700400341147713e-05)));
1.700400341147713e-05),
Vector3D.ZERO));
}
protected void setUpCliffsOfMoherContext()
throws RuggedException, OrekitException {
{
// cliffs of Moher location according to Wikipedia: 52°56′10″N 9°28′15″ W
GeodeticPoint north = new GeodeticPoint(FastMath.toRadians(52.9984),
......@@ -226,7 +224,7 @@ public abstract class AbstractAlgorithmTest {
FastMath.toRadians(-9.4369),
120.0);
// pixels are about 10m x 10m here and a tile covers 1km x 1km
// cells are about 10m x 10m here and a tile covers 1km x 1km
updater = new CliffsElevationUpdater(north, south,
120.0, 0.0,
FastMath.toRadians(0.015), 101);
......@@ -264,15 +262,16 @@ public abstract class AbstractAlgorithmTest {
true),
new Vector3D(-4.289600857433520e-05,
-1.039151496480297e-03,
5.811423736843181e-05)));
5.811423736843181e-05),
Vector3D.ZERO));
}
@Before
public void setUp()
throws OrekitException, URISyntaxException {
public void setUp() throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(new File(path)));
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
earth = new ExtendedEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, true));
......
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.intersection;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.orekit.rugged.api.AlgorithmId;
import org.orekit.rugged.raster.TileUpdater;
public class BasicScanAlgorithmTest extends AbstractAlgorithmTest {
public IntersectionAlgorithm createAlgorithm(final TileUpdater updater, final int maxCachedTiles) {
return new BasicScanAlgorithm(updater, maxCachedTiles);
}
@Test
public void testAlgorithmId() {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
assertEquals(AlgorithmId.BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY, algorithm.getAlgorithmId());
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.intersection;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.URISyntaxException;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.attitudes.Attitude;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.frames.FramesFactory;
import org.orekit.orbits.CartesianOrbit;
import org.orekit.propagation.SpacecraftState;
import org.orekit.rugged.api.AlgorithmId;
import org.orekit.rugged.intersection.duvenhage.DuvenhageAlgorithm;
import org.orekit.rugged.raster.CheckedPatternElevationUpdater;
import org.orekit.rugged.raster.TileUpdater;
import org.orekit.rugged.utils.ExtendedEllipsoid;
import org.orekit.rugged.utils.NormalizedGeodeticPoint;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
public class ConstantElevationAlgorithmTest {
@Test
public void testDuvenhageComparison() {
final Vector3D los = new Vector3D(-0.626242839, 0.0124194184, -0.7795291301);
IntersectionAlgorithm duvenhage = new DuvenhageAlgorithm(new CheckedPatternElevationUpdater(FastMath.toRadians(1.0),
256, 150.0, 150.0),
8, false);
IntersectionAlgorithm constantElevation = new ConstantElevationAlgorithm(150.0);
NormalizedGeodeticPoint gpRef = duvenhage.intersection(earth, state.getPVCoordinates().getPosition(), los);
NormalizedGeodeticPoint gpConst = constantElevation.intersection(earth, state.getPVCoordinates().getPosition(), los);
Assert.assertEquals(gpRef.getLatitude(), gpConst.getLatitude(), 1.0e-6);
Assert.assertEquals(gpRef.getLongitude(), gpConst.getLongitude(), 1.0e-6);
Assert.assertEquals(gpRef.getAltitude(), gpConst.getAltitude(), 1.0e-3);
Assert.assertEquals(150.0, constantElevation.getElevation(0.0, 0.0), 1.0e-3);
// shift longitude 2π
NormalizedGeodeticPoint shifted =
constantElevation.refineIntersection(earth, state.getPVCoordinates().getPosition(), los,
new NormalizedGeodeticPoint(gpConst.getLatitude(),
gpConst.getLongitude(),
gpConst.getAltitude(),
2 * FastMath.PI));
Assert.assertEquals(2 * FastMath.PI + gpConst.getLongitude(), shifted.getLongitude(), 1.0e-6);
}
@Test
public void testIgnoreDEMComparison() {
final Vector3D los = new Vector3D(-0.626242839, 0.0124194184, -0.7795291301);
IntersectionAlgorithm ignore = new IgnoreDEMAlgorithm();
IntersectionAlgorithm constantElevation = new ConstantElevationAlgorithm(0.0);
NormalizedGeodeticPoint gpRef = ignore.intersection(earth, state.getPVCoordinates().getPosition(), los);
NormalizedGeodeticPoint gpConst = constantElevation.intersection(earth, state.getPVCoordinates().getPosition(), los);
Assert.assertEquals(gpRef.getLatitude(), gpConst.getLatitude(), 1.0e-6);
Assert.assertEquals(gpRef.getLongitude(), gpConst.getLongitude(), 1.0e-6);
Assert.assertEquals(gpRef.getAltitude(), gpConst.getAltitude(), 1.0e-3);
Assert.assertEquals(0.0, constantElevation.getElevation(0.0, 0.0), 1.0e-3);
// shift longitude 2π
NormalizedGeodeticPoint shifted =
constantElevation.refineIntersection(earth, state.getPVCoordinates().getPosition(), los,
new NormalizedGeodeticPoint(gpConst.getLatitude(),
gpConst.getLongitude(),
gpConst.getAltitude(),
2 * FastMath.PI));
Assert.assertEquals(2 * FastMath.PI + gpConst.getLongitude(), shifted.getLongitude(), 1.0e-6);
// Simple test for test coverage purpose
double elevation0 = ignore.getElevation(gpRef.getLatitude(), gpConst.getLatitude());
Assert.assertEquals(elevation0, 0.0, 1.e-15);
}
@Test
public void testAlgorithmId() {
IntersectionAlgorithm constantElevation = new ConstantElevationAlgorithm(0.0);
assertEquals(AlgorithmId.CONSTANT_ELEVATION_OVER_ELLIPSOID, constantElevation.getAlgorithmId());
IntersectionAlgorithm ignore = new IgnoreDEMAlgorithm();
assertEquals(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID, ignore.getAlgorithmId());
}
@Before
public void setUp() throws URISyntaxException {
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
earth = new ExtendedEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, true));
AbsoluteDate crossing = new AbsoluteDate("2012-01-07T11:50:04.935272115", TimeScalesFactory.getUTC());
state = new SpacecraftState(new CartesianOrbit(new PVCoordinates(new Vector3D( 412324.544397459,
-4325872.329311633,
5692124.593989491),
new Vector3D(-1293.174701214779,
-5900.764863603793,
-4378.671036383179)),
FramesFactory.getEME2000(),
crossing,
Constants.EIGEN5C_EARTH_MU),
new Attitude(crossing,
FramesFactory.getEME2000(),
new Rotation(-0.17806699079182878,
0.60143347387211290,
-0.73251248177468900,
-0.26456641385623986,
true),
new Vector3D(-4.289600857433520e-05,
-1.039151496480297e-03,
5.811423736843181e-05),
Vector3D.ZERO));
}
@After
public void tearDown() {
earth = null;
updater = null;
state = null;
}
protected ExtendedEllipsoid earth;
protected TileUpdater updater;
protected SpacecraftState state;
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.intersection.duvenhage;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Test;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.errors.OrekitException;
import org.orekit.rugged.api.AlgorithmId;
import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.errors.RuggedMessages;
import org.orekit.rugged.intersection.AbstractAlgorithmTest;
import org.orekit.rugged.intersection.IntersectionAlgorithm;
import org.orekit.rugged.raster.CheckedPatternElevationUpdater;
import org.orekit.rugged.raster.Tile;
import org.orekit.rugged.raster.TileUpdater;
import org.orekit.rugged.raster.UpdatableTile;
import org.orekit.rugged.utils.ExtendedEllipsoid;
import org.orekit.rugged.utils.NormalizedGeodeticPoint;
public class DuvenhageAlgorithmTest extends AbstractAlgorithmTest {
protected IntersectionAlgorithm createAlgorithm(final TileUpdater updater, final int maxCachedTiles) {
return new DuvenhageAlgorithm(updater, maxCachedTiles, false);
}
@Test
public void testNumericalIssueAtTileExit() {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098);
Vector3D los = new Vector3D( 0.5127552821932051, -0.8254313129088879, -0.2361041470463311);
GeodeticPoint intersection = algorithm.refineIntersection(earth, position, los,
algorithm.intersection(earth, position, los));
checkIntersection(position, los, intersection);
}
@Test
public void testCrossingBeforeLineSegmentStart() {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
Vector3D position = new Vector3D(-3787079.6453602533, 5856784.405679551, 1655869.0582939098);
Vector3D los = new Vector3D( 0.42804005978915904, -0.8670291034054828, -0.2550338037664377);
GeodeticPoint intersection = algorithm.refineIntersection(earth, position, los,
algorithm.intersection(earth, position, los));
checkIntersection(position, los, intersection);
}
@Test
public void testWrongPositionMissesGround() {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
Vector3D position = new Vector3D(7.551889113912788E9, -3.173692685491814E10, 1.5727517321541348E9);
Vector3D los = new Vector3D(0.010401349221417867, -0.17836068905951286, 0.9839101973923178);
try {
algorithm.intersection(earth, position, los);
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.LINE_OF_SIGHT_DOES_NOT_REACH_GROUND, re.getSpecifier());
}
}
@Test
public void testInconsistentTileUpdater() {
final int n = 1201;
final double size = FastMath.toRadians(1.0);
updater = new TileUpdater() {
public void updateTile(double latitude, double longitude, UpdatableTile tile) {
double step = size / (n - 1);
// this geometry is incorrect:
// the specified latitude/longitude belong to rows/columns [1, n-1]
// and not [0, n-2].
tile.setGeometry(size * FastMath.floor(latitude / size) - 0.5 * step,
size * FastMath.floor(longitude / size) - 0.5 * step,
step, step, n, n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
tile.setElevation(i, j, ((i + j) % 2 == 0) ? -7.0 : 224);
}
}
}
};
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
try {
algorithm.intersection(earth,
new Vector3D(-3010311.9672771087, 5307094.8081077365, 1852867.7919871407),
new Vector3D(0.3953329359154183, -0.8654901360032332, -0.30763402650162286));
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.TILE_WITHOUT_REQUIRED_NEIGHBORS_SELECTED, re.getSpecifier());
}
}
@Test
public void testPureEastWestLOS() {
updater = new CheckedPatternElevationUpdater(FastMath.toRadians(1.0),1201, 41.0, 1563.0);
final IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
NormalizedGeodeticPoint gp =
algorithm.intersection(earth,
new Vector3D(-3041185.154503948, 6486750.132281409, -32335.022880173332),
new Vector3D(0.5660218606298548 , -0.8233939240951769, 0.040517885584811814));
Assert.assertEquals(1164.35, gp.getAltitude(), 0.02);
}
@Test
public void testParallelLOS() {
double size = 0.125;
int n = 129;
double elevation1 = 0.0;
double elevation2 = 100.0;
updater = new CheckedPatternElevationUpdater(size, n, elevation1, elevation2);
MinMaxTreeTile northTile = new MinMaxTreeTileFactory().createTile();
updater.updateTile((3 * size) / 2, (3 * size) / 2, northTile);
MinMaxTreeTile southTile = new MinMaxTreeTileFactory().createTile();
updater.updateTile((-3 * size) / 2, (3 * size) / 2, southTile);
IntersectionAlgorithm algorithm = createAlgorithm(updater, 8);
// line of sight in the South West corner
Assert.assertEquals(northTile.getMinimumLongitude() - 0.0625 * northTile.getLongitudeStep(),
findExit(algorithm, northTile,
new Vector3D( 6278799.86896170100, 788574.17965500170, 796074.70414069280),
new Vector3D( 0.09416282233912959, 0.01183204230132312, -0.99548649697728680)).getLongitude(),
1.0e-6);
// line of sight in the West column
Assert.assertEquals(northTile.getMinimumLongitude() - 0.0625 * northTile.getLongitudeStep(),
findExit(algorithm, northTile,
new Vector3D(6278799.868961701, 788574.17965500171, 796074.7041406928),
new Vector3D(0.09231669916268806, 0.011600067441452849, -0.9956621241621375)).getLongitude(),
1.0e-6);
// line of sight in the North-West corner
Assert.assertEquals(northTile.getMinimumLongitude() - 0.0625 * northTile.getLongitudeStep(),
findExit(algorithm, northTile,
new Vector3D( 6133039.79342824500, 770267.71434489540, 1568158.38266382620),
new Vector3D(-0.52028845147300570, -0.06537691642830394, -0.85148446025875800)).getLongitude(),
1.0e-6);
// line of sight in the North-East corner
Assert.assertEquals(northTile.getMaximumLongitude() + 0.0625 * northTile.getLongitudeStep(),
findExit(algorithm, northTile,
new Vector3D( 5988968.17708294100, 1529624.01701343130, 1568158.38266382620),
new Vector3D(-0.93877408645552440, -0.23970837882807683, -0.24747344851359457)).getLongitude(),
1.0e-6);
// line of sight in the East column
Assert.assertEquals(northTile.getMaximumLongitude() + 0.0625 * northTile.getLongitudeStep(),
findExit(algorithm, northTile,
new Vector3D( 6106093.15406747100, 1559538.54861392200, 979886.66862965740),
new Vector3D(-0.18115090486319424, -0.04625542007869719, 0.98236693031707310)).getLongitude(),
1.0e-6);
// line of sight in the South-East corner
Assert.assertEquals(northTile.getMaximumLongitude() + 0.0625 * northTile.getLongitudeStep(),
findExit(algorithm, northTile,
new Vector3D( 6131304.19368509600, 1565977.62301751650, 796074.70414069280),
new Vector3D( 0.09195297594530785, 0.02347944953986664, -0.99548649697728530)).getLongitude(),
1.0e-6);
// line of sight in the South row
Assert.assertEquals(northTile.getMinimumLatitude() - 0.0625 * northTile.getLatitudeStep(),
findExit(algorithm, northTile,
new Vector3D(6251729.731998736, 984354.4963428857, 789526.5774750853),
new Vector3D(-0.15561499277355603, 0.9878177838164719, 0.0)).getLatitude(),
1.0e-6);
// line of sight in the North row
Assert.assertEquals(southTile.getMaximumLatitude() + 0.0625 * southTile.getLatitudeStep(),
findExit(algorithm, southTile,
new Vector3D(6251729.731998736, 984354.4963428857, -789526.5774750853),
new Vector3D(-0.15561499277355603, 0.9878177838164719, 0.0)).getLatitude(),
1.0e-6);
}
@Test
public void testAlgorithmId() {
setUpMayonVolcanoContext();
final IntersectionAlgorithm algorithm = new DuvenhageAlgorithm(updater, 8, false);
assertEquals(AlgorithmId.DUVENHAGE, algorithm.getAlgorithmId());
final IntersectionAlgorithm algorithmFlatBody = new DuvenhageAlgorithm(updater, 8, true);
assertEquals(AlgorithmId.DUVENHAGE_FLAT_BODY, algorithmFlatBody.getAlgorithmId());
}
private NormalizedGeodeticPoint findExit(IntersectionAlgorithm algorithm, Tile tile, Vector3D position, Vector3D los) {
try {
Method findExit = DuvenhageAlgorithm.class.getDeclaredMethod("findExit",
Tile.class,
ExtendedEllipsoid.class,
Vector3D.class, Vector3D.class);
findExit.setAccessible(true);
Object limitPoint = findExit.invoke(algorithm, tile, earth, position, los);
Class<?> limitPointCls = null;
for (Class<?> c : DuvenhageAlgorithm.class.getDeclaredClasses()) {
if (c.getName().endsWith("LimitPoint")) {
limitPointCls = c;
}
}
Field pointField = limitPointCls.getDeclaredField("point");
pointField.setAccessible(true);
return (NormalizedGeodeticPoint) pointField.get(limitPoint);
} catch (NoSuchMethodException nsme) {
Assert.fail(nsme.getLocalizedMessage());
} catch (SecurityException se) {
Assert.fail(se.getLocalizedMessage());
} catch (IllegalAccessException iae) {
Assert.fail(iae.getLocalizedMessage());
} catch (IllegalArgumentException iae) {
Assert.fail(iae.getLocalizedMessage());
} catch (NoSuchFieldException nsfe) {
Assert.fail(nsfe.getLocalizedMessage());
} catch (InvocationTargetException e) {
if (e.getCause() instanceof RuggedException) {
throw (RuggedException) e.getCause();
} else {
throw (OrekitException) e.getCause();
}
}
return null;
}
}
/* Copyright 2013-2014 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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
......@@ -14,20 +14,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.rugged.core.duvenhage;
package org.orekit.rugged.intersection.duvenhage;
import org.hipparchus.random.RandomGenerator;
import org.hipparchus.random.Well1024a;
import org.hipparchus.util.FastMath;
import java.io.IOException;
import java.lang.reflect.Field;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.orekit.rugged.api.RuggedException;
import org.junit.rules.TemporaryFolder;
public class MinMaxTreeTileTest {
@Test
public void testSizeTall()
throws RuggedException, SecurityException, NoSuchFieldException,
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
MinMaxTreeTile tile = createTile(107, 19);
Assert.assertEquals(9, tile.getLevels());
......@@ -66,7 +71,7 @@ public class MinMaxTreeTileTest {
@Test
public void testSizeFat()
throws RuggedException, SecurityException, NoSuchFieldException,
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
MinMaxTreeTile tile = createTile(4, 7);
Assert.assertEquals(4, tile.getLevels());
......@@ -94,12 +99,12 @@ public class MinMaxTreeTileTest {
}
@Test
public void testSinglePixel() throws RuggedException {
public void testSinglePixel() {
Assert.assertEquals(0, createTile(1, 1).getLevels());
}
@Test
public void testMinMax() throws RuggedException {
public void testMinMax() {
for (int nbRows = 1; nbRows < 25; nbRows++) {
for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
......@@ -115,9 +120,9 @@ public class MinMaxTreeTileTest {
double max = Double.NEGATIVE_INFINITY;
for (int i = neighbors[0]; i < FastMath.min(neighbors[1] + 1, nbRows); ++i) {
for (int j = neighbors[2]; j < FastMath.min(neighbors[3] + 1, nbColumns); ++j) {
double pixelValue = tile.getElevationAtIndices(i, j);
min = FastMath.min(min, pixelValue);
max = FastMath.max(max, pixelValue);
double cellValue = tile.getElevationAtIndices(i, j);
min = FastMath.min(min, cellValue);
max = FastMath.max(max, cellValue);
}
}
......@@ -131,14 +136,63 @@ public class MinMaxTreeTileTest {
}
@Test
public void testMergeLarge() throws RuggedException {
public void testLocateMinMax() {
RandomGenerator random = new Well1024a(0xca9883209c6e740cl);
for (int nbRows = 1; nbRows < 25; nbRows++) {
for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
for (int i = 0; i < nbRows; ++i) {
for (int j = 0; j < nbColumns; ++j) {
final double e = 1000.0 * random.nextDouble();
tile.setElevation(i, j, e);
}
}
tile.tileUpdateCompleted();
for (int i = 0; i < tile.getLatitudeRows(); ++i) {
for (int j = 0; j < tile.getLongitudeColumns(); ++j) {
for (int l = 0; l < tile.getLevels(); ++l) {
int[] min = tile.locateMin(i, j, l);
Assert.assertEquals(tile.getMinElevation(i, j, l),
tile.getElevationAtIndices(min[0], min[1]),
1.0e-10);
int[] max = tile.locateMax(i, j, l);
Assert.assertEquals(tile.getMaxElevation(i, j, l),
tile.getElevationAtIndices(max[0], max[1]),
1.0e-10);
}
}
}
}
}
}
@Test
public void testIssue189() {
MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
tile.setGeometry(1.0, 2.0, 0.1, 0.2, 2, 2);
tile.setElevation(0, 0, 1.0);
tile.setElevation(0, 1, 2.0);
tile.setElevation(1, 0, 3.0);
tile.setElevation(1, 1, 4.0);
tile.tileUpdateCompleted();
Assert.assertEquals(1.0, tile.getMinElevation(0, 0, 0), 1.0e-10);
Assert.assertEquals(3.0, tile.getMinElevation(1, 0, 0), 1.0e-10);
Assert.assertEquals(4.0, tile.getMaxElevation(0, 0, 0), 1.0e-10);
Assert.assertEquals(4.0, tile.getMaxElevation(1, 0, 0), 1.0e-10);
}
@Test
public void testMergeLarge() {
MinMaxTreeTile tile = createTile(1201, 1201);
Assert.assertEquals(21, tile.getLevels());
Assert.assertEquals( 7, tile.getMergeLevel(703, 97, 765, 59));
}
@Test
public void testMergeLevel() throws RuggedException {
public void testMergeLevel() {
for (int nbRows = 1; nbRows < 20; nbRows++) {
for (int nbColumns = 1; nbColumns < 20; nbColumns++) {
......@@ -185,7 +239,7 @@ public class MinMaxTreeTileTest {
}
@Test
public void testSubTilesLimits() throws RuggedException {
public void testSubTilesLimits() {
for (int nbRows = 1; nbRows < 25; nbRows++) {
for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
......@@ -214,6 +268,17 @@ public class MinMaxTreeTileTest {
}
}
@Test
public void testForCoverage() throws IOException {
org.orekit.rugged.errors.DumpManager.activate(tempFolder.newFile());
MinMaxTreeTile tile = createTile(1201, 1201);
tile.getMinElevation(100, 100, 0);
org.orekit.rugged.errors.DumpManager.deactivate();
}
private int[] neighbors(int row, int column, int nbRows, int nbColumns, int stages) {
// poor man identification of neighbors cells merged together with specified cell
......@@ -284,7 +349,7 @@ public class MinMaxTreeTileTest {
}
private MinMaxTreeTile createTile(int nbRows, int nbColumns) throws RuggedException {
private MinMaxTreeTile createTile(int nbRows, int nbColumns) {
MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
for (int i = 0; i < nbRows; ++i) {
......@@ -295,5 +360,8 @@ public class MinMaxTreeTileTest {
tile.tileUpdateCompleted();
return tile;
}
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.linesensor;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.hipparchus.analysis.UnivariateMatrixFunction;
import org.hipparchus.analysis.differentiation.DSFactory;
import org.hipparchus.analysis.differentiation.DerivativeStructure;
import org.hipparchus.analysis.differentiation.FiniteDifferencesDifferentiator;
import org.hipparchus.analysis.differentiation.UnivariateDifferentiableMatrixFunction;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.RotationConvention;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.random.UncorrelatedRandomVectorGenerator;
import org.hipparchus.random.UniformRandomGenerator;
import org.hipparchus.random.Well19937a;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.rugged.los.FixedRotation;
import org.orekit.rugged.los.LOSBuilder;
import org.orekit.rugged.los.TimeDependentLOS;
import org.orekit.rugged.utils.DerivativeGenerator;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.ParameterDriver;
public class FixedRotationTest {
private List<Vector3D> raw;
@Test
public void testIdentity() {
UniformRandomGenerator rng = new UniformRandomGenerator(new Well19937a(0xaba71348a77d77cbl));
UncorrelatedRandomVectorGenerator rvg = new UncorrelatedRandomVectorGenerator(3, rng);
for (int k = 0; k < 20; ++k) {
LOSBuilder builder = new LOSBuilder(raw);
builder.addTransform(new FixedRotation("identity",
new Vector3D(rvg.nextVector()),
0.0));
TimeDependentLOS tdl = builder.build();
for (int i = 0; i < raw.size(); ++i) {
Assert.assertEquals(0.0,
Vector3D.distance(raw.get(i), tdl.getLOS(i, AbsoluteDate.J2000_EPOCH)),
2.0e-15);
}
Assert.assertEquals(1, tdl.getParametersDrivers().count());
Assert.assertEquals("identity", tdl.getParametersDrivers().findFirst().get().getName());
}
}
@Test
public void testCombination() {
UniformRandomGenerator rng = new UniformRandomGenerator(new Well19937a(0xefac03d9be4d24b9l));
UncorrelatedRandomVectorGenerator rvg = new UncorrelatedRandomVectorGenerator(3, rng);
for (int k = 0; k < 20; ++k) {
LOSBuilder builder = new LOSBuilder(raw);
Vector3D axis1 = new Vector3D(rvg.nextVector());
double angle1 = 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3);
builder.addTransform(new FixedRotation("r1", axis1, angle1));
Rotation r1 = new Rotation(axis1, angle1, RotationConvention.VECTOR_OPERATOR);
Vector3D axis2 = new Vector3D(rvg.nextVector());
double angle2 = 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3);
builder.addTransform(new FixedRotation("r2", axis2, angle2));
Rotation r2 = new Rotation(axis2, angle2, RotationConvention.VECTOR_OPERATOR);
Vector3D axis3 = new Vector3D(rvg.nextVector());
double angle3 = 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3);
builder.addTransform(new FixedRotation("r3", axis3, angle3));
Rotation r3 = new Rotation(axis3, angle3, RotationConvention.VECTOR_OPERATOR);
TimeDependentLOS tdl = builder.build();
Rotation combined = r3.applyTo(r2.applyTo(r1));
for (int i = 0; i < raw.size(); ++i) {
Assert.assertEquals(0.0,
Vector3D.distance(combined.applyTo(raw.get(i)),
tdl.getLOS(i, AbsoluteDate.J2000_EPOCH)),
2.0e-15);
}
List<ParameterDriver> drivers = tdl.getParametersDrivers().collect(Collectors.toList());
Assert.assertEquals(3, drivers.size());
ParameterDriver driver1 = drivers.get(0);
ParameterDriver driver2 = drivers.get(1);
ParameterDriver driver3 = drivers.get(2);
Assert.assertEquals("r1", driver1.getName());
Assert.assertEquals(-2 * FastMath.PI, driver1.getMinValue(), 2.0e-15);
Assert.assertEquals(+2 * FastMath.PI, driver1.getMaxValue(), 2.0e-15);
Assert.assertEquals(angle1, driver1.getValue(), 2.0e-15);
Assert.assertEquals("r2", driver2.getName());
Assert.assertEquals(-2 * FastMath.PI, driver2.getMinValue(), 2.0e-15);
Assert.assertEquals(+2 * FastMath.PI, driver2.getMaxValue(), 2.0e-15);
Assert.assertEquals(angle2, driver2.getValue(), 2.0e-15);
Assert.assertEquals("r3", driver3.getName());
Assert.assertEquals(-2 * FastMath.PI, driver3.getMinValue(), 2.0e-15);
Assert.assertEquals(+2 * FastMath.PI, driver3.getMaxValue(), 2.0e-15);
Assert.assertEquals(angle3, driver3.getValue(), 2.0e-15);
driver1.setValue(0.0);
driver2.setValue(0.0);
driver3.setValue(0.0);
for (int i = 0; i < raw.size(); ++i) {
Assert.assertEquals(0.0,
Vector3D.distance(raw.get(i),
tdl.getLOS(i, AbsoluteDate.J2000_EPOCH)),
2.0e-15);
}
}
}
@Test
public void testDerivatives() {
UniformRandomGenerator rng = new UniformRandomGenerator(new Well19937a(0xddae2b46b2207e08l));
UncorrelatedRandomVectorGenerator rvg = new UncorrelatedRandomVectorGenerator(3, rng);
for (int k = 0; k < 20; ++k) {
LOSBuilder builder = new LOSBuilder(raw);
builder.addTransform(new FixedRotation("r1",
new Vector3D(rvg.nextVector()),
2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3)));
builder.addTransform(new FixedRotation("r2",
new Vector3D(rvg.nextVector()),
2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3)));
builder.addTransform(new FixedRotation("r3",
new Vector3D(rvg.nextVector()),
2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3)));
TimeDependentLOS tdl = builder.build();
final List<ParameterDriver> selected = tdl.getParametersDrivers().collect(Collectors.toList());
for (final ParameterDriver driver : selected) {
driver.setSelected(true);
}
final DSFactory factoryS = new DSFactory(selected.size(), 1);
DerivativeGenerator<DerivativeStructure> generator = new DerivativeGenerator<DerivativeStructure>() {
/** {@inheritDoc} */
@Override
public List<ParameterDriver> getSelected() {
return selected;
}
/** {@inheritDoc} */
@Override
public DerivativeStructure constant(final double value) {
return factoryS.constant(value);
}
/** {@inheritDoc} */
@Override
public DerivativeStructure variable(final ParameterDriver driver) {
int index = 0;
for (ParameterDriver d : getSelected()) {
if (d == driver) {
return factoryS.variable(index, driver.getValue());
}
++index;
}
return constant(driver.getValue());
}
};
Assert.assertEquals(3, generator.getSelected().size());
FiniteDifferencesDifferentiator differentiator =
new FiniteDifferencesDifferentiator(4, 0.001);
int index = 0;
DSFactory factory11 = new DSFactory(1, 1);
for (final ParameterDriver driver : selected) {
int[] orders = new int[selected.size()];
orders[index] = 1;
UnivariateDifferentiableMatrixFunction f =
differentiator.differentiate((UnivariateMatrixFunction) x -> {
double oldX = driver.getValue();
double[][] matrix = new double[raw.size()][];
driver.setValue(x);
for (int i = 0 ; i < raw.size(); ++i) {
matrix[i] = tdl.getLOS(i, AbsoluteDate.J2000_EPOCH).toArray();
}
driver.setValue(oldX);
return matrix;
});
DerivativeStructure[][] mDS = f.value(factory11.variable(0, driver.getValue()));
for (int i = 0; i < raw.size(); ++i) {
Vector3D los = tdl.getLOS(i, AbsoluteDate.J2000_EPOCH);
FieldVector3D<DerivativeStructure> losDS =
tdl.getLOSDerivatives(i, AbsoluteDate.J2000_EPOCH, generator);
Assert.assertEquals(los.getX(), losDS.getX().getValue(), 2.0e-15);
Assert.assertEquals(los.getY(), losDS.getY().getValue(), 2.0e-15);
Assert.assertEquals(los.getZ(), losDS.getZ().getValue(), 2.0e-15);
Assert.assertEquals(mDS[i][0].getPartialDerivative(1), losDS.getX().getPartialDerivative(orders), 2.0e-12);
Assert.assertEquals(mDS[i][1].getPartialDerivative(1), losDS.getY().getPartialDerivative(orders), 2.0e-12);
Assert.assertEquals(mDS[i][2].getPartialDerivative(1), losDS.getZ().getPartialDerivative(orders), 2.0e-12);
}
++index;
}
}
}
@Before
public void setUp() throws URISyntaxException {
final Vector3D normal = Vector3D.PLUS_I;
final Vector3D fovCenter = Vector3D.PLUS_K;
final Vector3D cross = Vector3D.crossProduct(normal, fovCenter);
// build lists of pixels regularly spread on a perfect plane
raw = new ArrayList<Vector3D>();
for (int i = -100; i <= 100; ++i) {
final double alpha = i * 0.17 / 1000;
raw.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross));
}
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.linesensor;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.hipparchus.Field;
import org.hipparchus.analysis.UnivariateMatrixFunction;
import org.hipparchus.analysis.differentiation.DSFactory;
import org.hipparchus.analysis.differentiation.DerivativeStructure;
import org.hipparchus.analysis.differentiation.FiniteDifferencesDifferentiator;
import org.hipparchus.analysis.differentiation.Gradient;
import org.hipparchus.analysis.differentiation.GradientField;
import org.hipparchus.analysis.differentiation.UnivariateDifferentiableMatrixFunction;
import org.hipparchus.analysis.polynomials.PolynomialFunction;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.geometry.euclidean.threed.Rotation;
import org.hipparchus.geometry.euclidean.threed.RotationConvention;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.random.UncorrelatedRandomVectorGenerator;
import org.hipparchus.random.UniformRandomGenerator;
import org.hipparchus.random.Well19937a;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.rugged.los.LOSBuilder;
import org.orekit.rugged.los.PolynomialRotation;
import org.orekit.rugged.los.TimeDependentLOS;
import org.orekit.rugged.utils.DerivativeGenerator;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.ParameterDriver;
public class PolynomialRotationTest {
private List<Vector3D> raw;
@Test
public void testIdentity() {
UniformRandomGenerator rng = new UniformRandomGenerator(new Well19937a(0xbe0d9b530fe7f53cl));
UncorrelatedRandomVectorGenerator rvg = new UncorrelatedRandomVectorGenerator(3, rng);
for (int k = 0; k < 20; ++k) {
LOSBuilder builder = new LOSBuilder(raw);
builder.addTransform(new PolynomialRotation("identity",
new Vector3D(rvg.nextVector()),
AbsoluteDate.J2000_EPOCH, 0.0));
TimeDependentLOS tdl = builder.build();
for (int i = 0; i < raw.size(); ++i) {
Assert.assertEquals(0.0,
Vector3D.distance(raw.get(i), tdl.getLOS(i, AbsoluteDate.J2000_EPOCH)),
2.0e-15);
}
Assert.assertEquals(1, tdl.getParametersDrivers().count());
Assert.assertEquals("identity[0]", tdl.getParametersDrivers().findFirst().get().getName());
}
}
@Test
public void testFixedCombination() {
UniformRandomGenerator rng = new UniformRandomGenerator(new Well19937a(0xdc4cfdea38edd2bbl));
UncorrelatedRandomVectorGenerator rvg = new UncorrelatedRandomVectorGenerator(3, rng);
for (int k = 0; k < 20; ++k) {
LOSBuilder builder = new LOSBuilder(raw);
Vector3D axis1 = new Vector3D(rvg.nextVector());
double angle1 = 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3);
builder.addTransform(new PolynomialRotation("r1", axis1, AbsoluteDate.J2000_EPOCH, angle1));
Rotation r1 = new Rotation(axis1, angle1, RotationConvention.VECTOR_OPERATOR);
Vector3D axis2 = new Vector3D(rvg.nextVector());
double angle2 = 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3);
builder.addTransform(new PolynomialRotation("r2", axis2, AbsoluteDate.J2000_EPOCH, angle2));
Rotation r2 = new Rotation(axis2, angle2, RotationConvention.VECTOR_OPERATOR);
Vector3D axis3 = new Vector3D(rvg.nextVector());
double angle3 = 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3);
builder.addTransform(new PolynomialRotation("r3", axis3, AbsoluteDate.J2000_EPOCH, angle3));
Rotation r3 = new Rotation(axis3, angle3, RotationConvention.VECTOR_OPERATOR);
TimeDependentLOS tdl = builder.build();
Rotation combined = r3.applyTo(r2.applyTo(r1));
for (int i = 0; i < raw.size(); ++i) {
Assert.assertEquals(0.0,
Vector3D.distance(combined.applyTo(raw.get(i)),
tdl.getLOS(i, AbsoluteDate.J2000_EPOCH)),
2.0e-15);
}
List<ParameterDriver> drivers = tdl.getParametersDrivers().collect(Collectors.toList());
Assert.assertEquals(3, drivers.size());
ParameterDriver driver1 = drivers.get(0);
ParameterDriver driver2 = drivers.get(1);
ParameterDriver driver3 = drivers.get(2);
Assert.assertEquals("r1[0]", driver1.getName());
Assert.assertTrue(Double.isInfinite(driver1.getMinValue()));
Assert.assertTrue(driver1.getMinValue() < 0);
Assert.assertTrue(Double.isInfinite(driver1.getMaxValue()));
Assert.assertTrue(driver1.getMaxValue() > 0);
Assert.assertEquals(angle1, driver1.getValue(), 2.0e-15);
Assert.assertEquals("r2[0]", driver2.getName());
Assert.assertTrue(Double.isInfinite(driver2.getMinValue()));
Assert.assertTrue(driver2.getMinValue() < 0);
Assert.assertTrue(Double.isInfinite(driver2.getMaxValue()));
Assert.assertTrue(driver2.getMaxValue() > 0);
Assert.assertEquals(angle2, driver2.getValue(), 2.0e-15);
Assert.assertEquals("r3[0]", driver3.getName());
Assert.assertTrue(Double.isInfinite(driver3.getMinValue()));
Assert.assertTrue(driver3.getMinValue() < 0);
Assert.assertTrue(Double.isInfinite(driver3.getMaxValue()));
Assert.assertTrue(driver3.getMaxValue() > 0);
Assert.assertEquals(angle3, driver3.getValue(), 2.0e-15);
driver1.setValue(0.0);
driver2.setValue(0.0);
driver3.setValue(0.0);
for (int i = 0; i < raw.size(); ++i) {
Assert.assertEquals(0.0,
Vector3D.distance(raw.get(i),
tdl.getLOS(i, AbsoluteDate.J2000_EPOCH)),
2.0e-15);
}
}
}
@Test
public void testDerivatives() {
UniformRandomGenerator rng = new UniformRandomGenerator(new Well19937a(0xc60acfc04eb27935l));
UncorrelatedRandomVectorGenerator rvg = new UncorrelatedRandomVectorGenerator(3, rng);
for (int k = 0; k < 20; ++k) {
LOSBuilder builder = new LOSBuilder(raw);
builder.addTransform(new PolynomialRotation("r1",
new Vector3D(rvg.nextVector()),
AbsoluteDate.J2000_EPOCH,
2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3),
1.0e-4 * 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3)));
builder.addTransform(new PolynomialRotation("r2",
new Vector3D(rvg.nextVector()),
AbsoluteDate.J2000_EPOCH,
new PolynomialFunction(new double[] {
2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3),
1.0e-4 * 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3),
1.0e-8 * 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3)
})));
builder.addTransform(new PolynomialRotation("r3",
new Vector3D(rvg.nextVector()),
AbsoluteDate.J2000_EPOCH,
2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3),
1.0e-4 * 2 * FastMath.PI * rng.nextNormalizedDouble() / FastMath.sqrt(3)));
TimeDependentLOS tdl = builder.build();
final List<ParameterDriver> selected = tdl.getParametersDrivers().collect(Collectors.toList());
for (final ParameterDriver driver : selected) {
driver.setSelected(true);
}
final GradientField field = GradientField.getField(selected.size());
DerivativeGenerator<Gradient> generator = new DerivativeGenerator<Gradient>() {
/** {@inheritDoc} */
@Override
public List<ParameterDriver> getSelected() {
return selected;
}
/** {@inheritDoc} */
@Override
public Gradient constant(final double value) {
return Gradient.constant(selected.size(), value);
}
/** {@inheritDoc} */
@Override
public Gradient variable(final ParameterDriver driver) {
int index = 0;
for (ParameterDriver d : getSelected()) {
if (d == driver) {
return Gradient.variable(selected.size(), index, driver.getValue());
}
++index;
}
return constant(driver.getValue());
}
/** {@inheritDoc} */
@Override
public Field<Gradient> getField() {
return field;
}
};
Assert.assertEquals(7, generator.getSelected().size());
FiniteDifferencesDifferentiator differentiator =
new FiniteDifferencesDifferentiator(4, 0.0001);
int index = 0;
DSFactory factory11 = new DSFactory(1, 1);
final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(7.0);
for (final ParameterDriver driver : selected) {
int[] orders = new int[selected.size()];
orders[index] = 1;
UnivariateDifferentiableMatrixFunction f =
differentiator.differentiate((UnivariateMatrixFunction) x -> {
double oldX = driver.getValue();
double[][] matrix = new double[raw.size()][];
driver.setValue(x);
for (int i = 0 ; i < raw.size(); ++i) {
matrix[i] = tdl.getLOS(i, date).toArray();
}
driver.setValue(oldX);
return matrix;
});
DerivativeStructure[][] mDS = f.value(factory11.variable(0, driver.getValue()));
for (int i = 0; i < raw.size(); ++i) {
Vector3D los = tdl.getLOS(i, date);
FieldVector3D<Gradient> losDS = tdl.getLOSDerivatives(i, date, generator);
Assert.assertEquals(los.getX(), losDS.getX().getValue(), 2.0e-15);
Assert.assertEquals(los.getY(), losDS.getY().getValue(), 2.0e-15);
Assert.assertEquals(los.getZ(), losDS.getZ().getValue(), 2.0e-15);
Assert.assertEquals(mDS[i][0].getPartialDerivative(1), losDS.getX().getPartialDerivative(orders), 2.0e-10);
Assert.assertEquals(mDS[i][1].getPartialDerivative(1), losDS.getY().getPartialDerivative(orders), 2.0e-10);
Assert.assertEquals(mDS[i][2].getPartialDerivative(1), losDS.getZ().getPartialDerivative(orders), 2.0e-10);
}
++index;
}
}
}
@Before
public void setUp() throws URISyntaxException {
final Vector3D normal = Vector3D.PLUS_I;
final Vector3D fovCenter = Vector3D.PLUS_K;
final Vector3D cross = Vector3D.crossProduct(normal, fovCenter);
// build lists of pixels regularly spread on a perfect plane
raw = new ArrayList<Vector3D>();
for (int i = -100; i <= 100; ++i) {
final double alpha = i * 0.17 / 1000;
raw.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross));
}
}
}
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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.linesensor;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.hipparchus.geometry.euclidean.threed.Line;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.random.RandomGenerator;
import org.hipparchus.random.Well19937a;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.attitudes.NadirPointing;
import org.orekit.attitudes.YawCompensation;
import org.orekit.bodies.BodyShape;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.data.DataContext;
import org.orekit.data.DirectoryCrawler;
import org.orekit.frames.FramesFactory;
import org.orekit.frames.Transform;
import org.orekit.orbits.CircularOrbit;
import org.orekit.orbits.Orbit;
import org.orekit.orbits.PositionAngle;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.analytical.KeplerianPropagator;
import org.orekit.rugged.TestUtils;
import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.errors.RuggedMessages;
import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing.CrossingResult;
import org.orekit.rugged.los.LOSBuilder;
import org.orekit.rugged.utils.SpacecraftToObservedBody;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.AngularDerivativesFilter;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.TimeStampedAngularCoordinates;
import org.orekit.utils.TimeStampedPVCoordinates;
public class SensorMeanPlaneCrossingTest {
@Test
public void testPerfectLine() {
final Vector3D position = new Vector3D(1.5, Vector3D.PLUS_I);
final Vector3D normal = Vector3D.PLUS_I;
final Vector3D fovCenter = Vector3D.PLUS_K;
final Vector3D cross = Vector3D.crossProduct(normal, fovCenter);
// build lists of pixels regularly spread on a perfect plane
final List<Vector3D> los = new ArrayList<Vector3D>();
for (int i = -1000; i <= 1000; ++i) {
final double alpha = i * 0.17 / 1000;
los.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross));
}
final LineSensor sensor = new LineSensor("perfect line",
new LinearLineDatation(AbsoluteDate.J2000_EPOCH, 0.0, 1.0 / 1.5e-3),
position, new LOSBuilder(los).build());
Assert.assertEquals("perfect line", sensor.getName());
Assert.assertEquals(AbsoluteDate.J2000_EPOCH, sensor.getDate(0.0));
Assert.assertEquals(0.0, Vector3D.distance(position, sensor.getPosition()), 1.0e-15);
SensorMeanPlaneCrossing mean = new SensorMeanPlaneCrossing(sensor, createInterpolator(sensor),
0, 2000, true, true, 50, 0.01);
Assert.assertEquals(0.0, Vector3D.angle(normal, mean.getMeanPlaneNormal()), 1.0e-15);
}
@Test
public void testNoisyLine() {
final RandomGenerator random = new Well19937a(0xf3ddb33785e12bdal);
final Vector3D position = new Vector3D(1.5, Vector3D.PLUS_I);
final Vector3D normal = Vector3D.PLUS_I;
final Vector3D fovCenter = Vector3D.PLUS_K;
final Vector3D cross = Vector3D.crossProduct(normal, fovCenter);
// build lists of pixels regularly spread on a perfect plane
final List<Vector3D> los = new ArrayList<Vector3D>();
for (int i = -1000; i <= 1000; ++i) {
final double alpha = i * 0.17 / 10 + 1.0e-5 * random.nextDouble();
final double delta = 1.0e-5 * random.nextDouble();
final double cA = FastMath.cos(alpha);
final double sA = FastMath.sin(alpha);
final double cD = FastMath.cos(delta);
final double sD = FastMath.sin(delta);
los.add(new Vector3D(cA * cD, fovCenter, sA * cD, cross, sD, normal));
}
final LineSensor sensor = new LineSensor("noisy line",
new LinearLineDatation(AbsoluteDate.J2000_EPOCH, 0.0, 1.0 / 1.5e-3),
position, new LOSBuilder(los).build());
Assert.assertEquals("noisy line", sensor.getName());
Assert.assertEquals(AbsoluteDate.J2000_EPOCH, sensor.getDate(0.0));
Assert.assertEquals(0.0, Vector3D.distance(position, sensor.getPosition()), 1.0e-5);
SensorMeanPlaneCrossing mean = new SensorMeanPlaneCrossing(sensor, createInterpolator(sensor),
0, 2000, true, true, 50, 0.01);
Assert.assertEquals(0.0, Vector3D.angle(normal, mean.getMeanPlaneNormal()), 8.0e-7);
}
@Test
public void testDerivativeWithoutCorrections() {
doTestDerivative(false, false, 3.1e-11);
}
@Test
public void testDerivativeLightTimeCorrection() {
doTestDerivative(true, false, 2.4e-7);
}
@Test
public void testDerivativeAberrationOfLightCorrection() {
doTestDerivative(false, true, 1.1e-7);
}
@Test
public void testDerivativeWithAllCorrections() {
doTestDerivative(true, true, 1.4e-7);
}
private void doTestDerivative(boolean lightTimeCorrection,
boolean aberrationOfLightCorrection,
double tol) {
final Vector3D position = new Vector3D(1.5, Vector3D.PLUS_I);
final Vector3D normal = Vector3D.PLUS_I;
final Vector3D fovCenter = Vector3D.PLUS_K;
final Vector3D cross = Vector3D.crossProduct(normal, fovCenter);
// build lists of pixels regularly spread on a perfect plane
final List<Vector3D> los = new ArrayList<Vector3D>();
for (int i = -1000; i <= 1000; ++i) {
final double alpha = i * 0.17 / 1000;
los.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross));
}
final LineSensor sensor = new LineSensor("perfect line",
new LinearLineDatation(AbsoluteDate.J2000_EPOCH, 0.0, 1.0 / 1.5e-3),
position, new LOSBuilder(los).build());
Assert.assertEquals("perfect line", sensor.getName());
Assert.assertEquals(AbsoluteDate.J2000_EPOCH, sensor.getDate(0.0));
Assert.assertEquals(0.0, Vector3D.distance(position, sensor.getPosition()), 1.0e-15);
SensorMeanPlaneCrossing mean = new SensorMeanPlaneCrossing(sensor, createInterpolator(sensor),
0, 2000, lightTimeCorrection,
aberrationOfLightCorrection, 50, 1.0e-6);
double refLine = 1200.0;
AbsoluteDate refDate = sensor.getDate(refLine);
int refPixel= 1800;
Transform b2i = mean.getScToBody().getBodyToInertial(refDate);
Transform sc2i = mean.getScToBody().getScToInertial(refDate);
Transform sc2b = new Transform(refDate, sc2i, b2i.getInverse());
Vector3D p1 = sc2b.transformPosition(position);
Vector3D p2 = sc2b.transformPosition(new Vector3D(1, position,
1.0e6, los.get(refPixel)));
Line line = new Line(p1, p2, 0.001);
BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
mean.getScToBody().getBodyFrame());
GeodeticPoint groundPoint = earth.getIntersectionPoint(line, p1, mean.getScToBody().getBodyFrame(), refDate);
Vector3D gpCartesian = earth.transform(groundPoint);
SensorMeanPlaneCrossing.CrossingResult result = mean.find(gpCartesian);
if (lightTimeCorrection) {
// applying corrections shifts the point with respect
// to the reference result computed from a simple model above
Assert.assertTrue(result.getLine() - refLine > 0.02);
} else if (aberrationOfLightCorrection) {
// applying corrections shifts the point with respect
// to the reference result computed from a simple model above
Assert.assertTrue(result.getLine() - refLine > 1.9);
} else {
// the simple model from which reference results have been compute applies here
Assert.assertEquals(refLine, result.getLine(), 5.0e-11* refLine);
Assert.assertEquals(0.0, result.getDate().durationFrom(refDate), 1.0e-9);
Assert.assertEquals(0.0, Vector3D.angle(los.get(refPixel), result.getTargetDirection()), 5.4e-15);
}
double deltaL = 0.5;
Transform b2scPlus = sc2b.getInverse().shiftedBy(deltaL / sensor.getRate(refLine));
Vector3D dirPlus = b2scPlus.transformPosition(gpCartesian).subtract(position).normalize();
Transform b2scMinus = sc2b.getInverse().shiftedBy(-deltaL / sensor.getRate(refLine));
Vector3D dirMinus = b2scMinus.transformPosition(gpCartesian).subtract(position).normalize();
Vector3D dirDer = new Vector3D(1.0 / (2 * deltaL), dirPlus.subtract(dirMinus));
Assert.assertEquals(0.0,
Vector3D.distance(result.getTargetDirectionDerivative(), dirDer),
tol * dirDer.getNorm());
try {
mean.getScToBody().getBodyToInertial(refDate.shiftedBy(-Constants.JULIAN_CENTURY));
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
}
try {
mean.getScToBody().getBodyToInertial(refDate.shiftedBy(Constants.JULIAN_CENTURY));
Assert.fail("an exception should have been thrown");
} catch (RuggedException re) {
Assert.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
}
Assert.assertNotNull(mean.getScToBody().getBodyToInertial(refDate));
}
@Test
public void testSlowFind()
throws NoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
final Vector3D position = new Vector3D(1.5, Vector3D.PLUS_I);
final Vector3D normal = Vector3D.PLUS_I;
final Vector3D fovCenter = Vector3D.PLUS_K;
final Vector3D cross = Vector3D.crossProduct(normal, fovCenter);
// build lists of pixels regularly spread on a perfect plane
final List<Vector3D> los = new ArrayList<Vector3D>();
for (int i = -1000; i <= 1000; ++i) {
final double alpha = i * 0.17 / 1000;
los.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross));
}
final LineSensor sensor = new LineSensor("perfect line",
new LinearLineDatation(AbsoluteDate.J2000_EPOCH, 0.0, 1.0 / 1.5e-3),
position, new LOSBuilder(los).build());
Assert.assertEquals("perfect line", sensor.getName());
Assert.assertEquals(AbsoluteDate.J2000_EPOCH, sensor.getDate(0.0));
Assert.assertEquals(0.0, Vector3D.distance(position, sensor.getPosition()), 1.0e-15);
SensorMeanPlaneCrossing mean = new SensorMeanPlaneCrossing(sensor, createInterpolator(sensor),
0, 2000, true, true, 50, 1.0e-6);
double refLine = 1200.0;
AbsoluteDate refDate = sensor.getDate(refLine);
int refPixel= 1800;
Transform b2i = mean.getScToBody().getBodyToInertial(refDate);
Transform sc2i = mean.getScToBody().getScToInertial(refDate);
Transform sc2b = new Transform(refDate, sc2i, b2i.getInverse());
Vector3D p1 = sc2b.transformPosition(position);
Vector3D p2 = sc2b.transformPosition(new Vector3D(1, position,
1.0e6, los.get(refPixel)));
Line line = new Line(p1, p2, 0.001);
BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
mean.getScToBody().getBodyFrame());
GeodeticPoint groundPoint = earth.getIntersectionPoint(line, p1, mean.getScToBody().getBodyFrame(), refDate);
Vector3D gpCartesian = earth.transform(groundPoint);
SensorMeanPlaneCrossing.CrossingResult result = mean.find(gpCartesian);
Method slowFind = SensorMeanPlaneCrossing.class.getDeclaredMethod("slowFind",
PVCoordinates.class,
Double.TYPE);
slowFind.setAccessible(true);
SensorMeanPlaneCrossing.CrossingResult slowResult =
(CrossingResult) slowFind.invoke(mean,
new PVCoordinates(gpCartesian, Vector3D.ZERO),
400.0);
Assert.assertEquals(result.getLine(), slowResult.getLine(), 2.0e-8);
Assert.assertEquals(0.0,
Vector3D.distance(result.getTargetDirection(),
slowResult.getTargetDirection()),
2.0e-13);
Assert.assertEquals(0.0,
Vector3D.distance(result.getTargetDirectionDerivative(),
slowResult.getTargetDirectionDerivative()),
1.0e-15);
}
private SpacecraftToObservedBody createInterpolator(LineSensor sensor) {
Orbit orbit = new CircularOrbit(7173352.811913891,
-4.029194321683225E-4, 0.0013530362644647786,
FastMath.toRadians(98.63218182243709),
FastMath.toRadians(77.55565567747836),
FastMath.PI, PositionAngle.TRUE,
FramesFactory.getEME2000(), sensor.getDate(1000),
Constants.EIGEN5C_EARTH_MU);
BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, true));
AbsoluteDate minDate = sensor.getDate(0);
AbsoluteDate maxDate = sensor.getDate(2000);
return new SpacecraftToObservedBody(orbit.getFrame(), earth.getBodyFrame(),
minDate, maxDate, 0.01,
5.0,
orbitToPV(orbit, earth, minDate, maxDate, 0.25), 2,
CartesianDerivativesFilter.USE_P,
orbitToQ(orbit, earth, minDate, maxDate, 0.25), 2,
AngularDerivativesFilter.USE_R);
}
private List<TimeStampedPVCoordinates> orbitToPV(Orbit orbit, BodyShape earth,
AbsoluteDate minDate, AbsoluteDate maxDate,
double step) {
Propagator propagator = new KeplerianPropagator(orbit);
propagator.setAttitudeProvider(new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth)));
propagator.propagate(minDate);
final List<TimeStampedPVCoordinates> list = new ArrayList<TimeStampedPVCoordinates>();
propagator.getMultiplexer().add(step, currentState -> list.add(new TimeStampedPVCoordinates(currentState.getDate(),
currentState.getPVCoordinates().getPosition(),
currentState.getPVCoordinates().getVelocity(),
Vector3D.ZERO)));
propagator.propagate(maxDate);
return list;
}
private List<TimeStampedAngularCoordinates> orbitToQ(Orbit orbit, BodyShape earth,
AbsoluteDate minDate, AbsoluteDate maxDate,
double step) {
Propagator propagator = new KeplerianPropagator(orbit);
propagator.setAttitudeProvider(new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth)));
propagator.propagate(minDate);
final List<TimeStampedAngularCoordinates> list = new ArrayList<TimeStampedAngularCoordinates>();
propagator.getMultiplexer().add(step, currentState -> list.add(new TimeStampedAngularCoordinates(currentState.getDate(),
currentState.getAttitude().getRotation(),
Vector3D.ZERO, Vector3D.ZERO)));
propagator.propagate(maxDate);
return list;
}
@Before
public void setUp() throws URISyntaxException {
TestUtils.clearFactories();
String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
}
}
/* Copyright 2013-2014 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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
......@@ -14,12 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.rugged.core.raster;
package org.orekit.rugged.raster;
import org.apache.commons.math3.util.FastMath;
import org.orekit.rugged.api.RuggedException;
import org.orekit.rugged.api.TileUpdater;
import org.orekit.rugged.api.UpdatableTile;
import org.hipparchus.util.FastMath;
public class CheckedPatternElevationUpdater implements TileUpdater {
......@@ -35,8 +32,8 @@ public class CheckedPatternElevationUpdater implements TileUpdater {
this.elevation2 = elevation2;
}
public void updateTile(double latitude, double longitude, UpdatableTile tile)
throws RuggedException {
public void updateTile(double latitude, double longitude, UpdatableTile tile) {
double step = size / (n - 1);
double minLatitude = size * FastMath.floor(latitude / size);
double minLongitude = size * FastMath.floor(longitude / size);
......
/* Copyright 2013-2014 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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
......@@ -14,13 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.rugged.core.raster;
package org.orekit.rugged.raster;
import org.apache.commons.math3.util.FastMath;
import org.hipparchus.util.FastMath;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.rugged.api.RuggedException;
import org.orekit.rugged.api.TileUpdater;
import org.orekit.rugged.api.UpdatableTile;
public class CliffsElevationUpdater implements TileUpdater {
......@@ -42,8 +39,8 @@ public class CliffsElevationUpdater implements TileUpdater {
this.n = n;
}
public void updateTile(double latitude, double longitude, UpdatableTile tile)
throws RuggedException {
public void updateTile(double latitude, double longitude, UpdatableTile tile) {
double step = size / (n - 1);
double minLatitude = size * FastMath.floor(latitude / size);
double minLongitude = size * FastMath.floor(longitude / size);
......@@ -51,11 +48,11 @@ public class CliffsElevationUpdater implements TileUpdater {
double y2My1 = point2.getLatitude() - point1.getLatitude();
tile.setGeometry(minLatitude, minLongitude, step, step, n, n);
for (int i = 0; i < n; ++i) {
double pixelLatitude = minLatitude + i * step;
double cellLatitude = minLatitude + i * step;
for (int j = 0; j < n; ++j) {
double pixelLongitude = minLongitude + j * step;
double xMx1 = pixelLongitude - point1.getLongitude();
double yMy1 = pixelLatitude - point1.getLatitude();
double cellLongitude = minLongitude + j * step;
double xMx1 = cellLongitude - point1.getLongitude();
double yMy1 = cellLatitude - point1.getLatitude();
if (yMy1 * x2Mx1 > xMx1 * y2My1) {
// left side of the point1 to point2 track
tile.setElevation(i, j, top);
......
/* Copyright 2013-2014 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
/* Copyright 2013-2022 CS GROUP
* Licensed to CS GROUP (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
......@@ -14,11 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.rugged.core.raster;
import org.orekit.rugged.core.raster.SimpleTile;
import org.orekit.rugged.core.raster.SimpleTileFactory;
import org.orekit.rugged.core.raster.TileFactory;
package org.orekit.rugged.raster;
public class CountingFactory implements TileFactory<SimpleTile> {
......