/* Copyright 2002-2017 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.frames; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.hipparchus.RealFieldElement; 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.Test; import org.orekit.errors.OrekitException; import org.orekit.errors.OrekitMessages; import org.orekit.time.AbsoluteDate; import org.orekit.time.FieldAbsoluteDate; import org.orekit.utils.AngularDerivativesFilter; import org.orekit.utils.CartesianDerivativesFilter; public class ShiftingTransformProviderTest { @Test public void testCacheHitForward() throws OrekitException { AbsoluteDate t0 = AbsoluteDate.GALILEO_EPOCH; CirclingProvider referenceProvider = new CirclingProvider(t0, 0.2); CirclingProvider rawProvider = new CirclingProvider(t0, 0.2); ShiftingTransformProvider shiftingProvider = new ShiftingTransformProvider(rawProvider, CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_RRA, AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY, 5, 0.8, 10, 60.0, 60.0); Assert.assertEquals(5, shiftingProvider.getGridPoints()); Assert.assertEquals(0.8, shiftingProvider.getStep(), 1.0e-15); for (double dt = 0.8; dt <= 1.0; dt += 0.001) { Transform reference = referenceProvider.getTransform(t0.shiftedBy(dt)); Transform interpolated = shiftingProvider.getTransform(t0.shiftedBy(dt)); Transform error = new Transform(reference.getDate(), reference, interpolated.getInverse()); Assert.assertEquals(0.0, error.getCartesian().getPosition().getNorm(), 1.1e-5); Assert.assertEquals(0.0, error.getCartesian().getVelocity().getNorm(), 1.6e-4); Assert.assertEquals(0.0, error.getCartesian().getAcceleration().getNorm(), 1.6e-3); Assert.assertEquals(0.0, error.getAngular().getRotation().getAngle(), 4.2e-16); Assert.assertEquals(0.0, error.getAngular().getRotationRate().getNorm(), 1.2e-16); Assert.assertEquals(0.0, error.getAngular().getRotationAcceleration().getNorm(), 7.1e-30); } Assert.assertEquals(8, rawProvider.getCount()); Assert.assertEquals(200, referenceProvider.getCount()); } @Test public void testCacheHitBackward() throws OrekitException { AbsoluteDate t0 = AbsoluteDate.GALILEO_EPOCH; CirclingProvider referenceProvider = new CirclingProvider(t0, 0.2); CirclingProvider rawProvider = new CirclingProvider(t0, 0.2); ShiftingTransformProvider shiftingProvider = new ShiftingTransformProvider(rawProvider, CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_RRA, AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY, 5, 0.8, 10, 60.0, 60.0); Assert.assertEquals(5, shiftingProvider.getGridPoints()); Assert.assertEquals(0.8, shiftingProvider.getStep(), 1.0e-15); for (double dt = 1.0; dt >= 0.8; dt -= 0.001) { Transform reference = referenceProvider.getTransform(t0.shiftedBy(dt)); Transform interpolated = shiftingProvider.getTransform(t0.shiftedBy(dt)); Transform error = new Transform(reference.getDate(), reference, interpolated.getInverse()); Assert.assertEquals(0.0, error.getCartesian().getPosition().getNorm(), 1.1e-5); Assert.assertEquals(0.0, error.getCartesian().getVelocity().getNorm(), 1.6e-4); Assert.assertEquals(0.0, error.getCartesian().getAcceleration().getNorm(), 1.6e-3); Assert.assertEquals(0.0, error.getAngular().getRotation().getAngle(), 4.2e-16); Assert.assertEquals(0.0, error.getAngular().getRotationRate().getNorm(), 2.3e-16); Assert.assertEquals(0.0, error.getAngular().getRotationAcceleration().getNorm(), 7.1e-30); } Assert.assertEquals(10, rawProvider.getCount()); Assert.assertEquals(200, referenceProvider.getCount()); } @Test(expected=OrekitException.class) public void testForwardException() throws OrekitException { ShiftingTransformProvider shiftingProvider = new ShiftingTransformProvider(new TransformProvider() { private static final long serialVersionUID = -3126512810306982868L; public Transform getTransform(AbsoluteDate date) throws OrekitException { throw new OrekitException(OrekitMessages.INTERNAL_ERROR); } public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) { throw new UnsupportedOperationException("never called in this test"); } }, CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_RRA, AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY, 5, 0.8, 10, 60.0, 60.0); shiftingProvider.getTransform(AbsoluteDate.J2000_EPOCH); } @Test public void testSerialization() throws OrekitException, IOException, ClassNotFoundException { AbsoluteDate t0 = AbsoluteDate.GALILEO_EPOCH; CirclingProvider rawProvider = new CirclingProvider(t0, 0.2); ShiftingTransformProvider shiftingProvider = new ShiftingTransformProvider(rawProvider, CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_RRA, AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY, 5, 0.8, 10, 60.0, 60.0); for (double dt = 0.1; dt <= 3.1; dt += 0.001) { shiftingProvider.getTransform(t0.shiftedBy(dt)); } Assert.assertEquals(12, rawProvider.getCount()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(shiftingProvider); Assert.assertTrue(bos.size () > 700); Assert.assertTrue(bos.size () < 800); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ShiftingTransformProvider deserialized = (ShiftingTransformProvider) ois.readObject(); Assert.assertEquals(0, ((CirclingProvider) deserialized.getRawProvider()).getCount()); for (double dt = 0.1; dt <= 3.1; dt += 0.001) { Transform t1 = shiftingProvider.getTransform(t0.shiftedBy(dt)); Transform t2 = deserialized.getTransform(t0.shiftedBy(dt)); Transform error = new Transform(t1.getDate(), t1, t2.getInverse()); // both interpolators should give the same results Assert.assertEquals(0.0, error.getCartesian().getPosition().getNorm(), 1.0e-15); Assert.assertEquals(0.0, error.getCartesian().getVelocity().getNorm(), 1.0e-15); Assert.assertEquals(0.0, error.getAngular().getRotation().getAngle(), 1.0e-15); Assert.assertEquals(0.0, error.getAngular().getRotationRate().getNorm(), 1.0e-15); } // the original interpolator should not have triggered any new calls Assert.assertEquals(12, rawProvider.getCount()); // the deserialized interpolator should have triggered new calls Assert.assertEquals(12, ((CirclingProvider) deserialized.getRawProvider()).getCount()); } private static class CirclingProvider implements TransformProvider { private static final long serialVersionUID = 473784183299281612L; private int count; private final AbsoluteDate t0; private final double omega; public CirclingProvider(final AbsoluteDate t0, final double omega) { this.count = 0; this.t0 = t0; this.omega = omega; } public Transform getTransform(final AbsoluteDate date) { // the following transform corresponds to a frame moving along the circle r = 1 // with its x axis always pointing to the reference frame center ++count; final double dt = date.durationFrom(t0); final double cos = FastMath.cos(omega * dt); final double sin = FastMath.sin(omega * dt); return new Transform(date, new Transform(date, new Vector3D(-cos, -sin, 0), new Vector3D(omega * sin, -omega * cos, 0), new Vector3D(omega * omega * cos, omega * omega * sin, 0)), new Transform(date, new Rotation(Vector3D.PLUS_K, FastMath.PI - omega * dt, RotationConvention.VECTOR_OPERATOR), new Vector3D(omega, Vector3D.PLUS_K))); } public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) { throw new UnsupportedOperationException("never called in this test"); } public int getCount() { return count; } private Object readResolve() { count = 0; return this; } } }