/* 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.estimation.measurements; import java.util.List; import org.hipparchus.stat.descriptive.rank.Median; import org.hipparchus.util.FastMath; import org.junit.Assert; import org.junit.Test; import org.orekit.errors.OrekitException; import org.orekit.estimation.Context; import org.orekit.estimation.EstimationTestUtils; import org.orekit.estimation.EstimationUtils; import org.orekit.estimation.StateFunction; import org.orekit.orbits.OrbitType; import org.orekit.orbits.PositionAngle; import org.orekit.propagation.Propagator; import org.orekit.propagation.SpacecraftState; import org.orekit.propagation.conversion.NumericalPropagatorBuilder; import org.orekit.time.AbsoluteDate; public class PVTest { @Test public void testStateDerivatives() throws OrekitException { Context context = EstimationTestUtils.eccentricContext(); final NumericalPropagatorBuilder propagatorBuilder = context.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true, 1.0e-6, 60.0, 0.001); // create perfect range measurements final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit, propagatorBuilder); final List<ObservedMeasurement<?>> measurements = EstimationTestUtils.createMeasurements(propagator, new PVMeasurementCreator(), 1.0, 3.0, 300.0); propagator.setSlaveMode(); double[] errorsP = new double[3 * 6 * measurements.size()]; double[] errorsV = new double[3 * 6 * measurements.size()]; int indexP = 0; int indexV = 0; for (final ObservedMeasurement<?> measurement : measurements) { final AbsoluteDate date = measurement.getDate(); final SpacecraftState state = propagator.propagate(date); final double[][] jacobian = measurement.estimate(0, 0, state).getStateDerivatives(); // compute a reference value using finite differences final double[][] finiteDifferencesJacobian = EstimationUtils.differentiate(new StateFunction() { public double[] value(final SpacecraftState state) throws OrekitException { return measurement.estimate(0, 0, state).getEstimatedValue(); } }, measurement.getDimension(), OrbitType.CARTESIAN, PositionAngle.TRUE, 1.0, 3).value(state); Assert.assertEquals(finiteDifferencesJacobian.length, jacobian.length); Assert.assertEquals(finiteDifferencesJacobian[0].length, jacobian[0].length); for (int i = 0; i < jacobian.length; ++i) { for (int j = 0; j < jacobian[i].length; ++j) { final double relativeError = FastMath.abs((finiteDifferencesJacobian[i][j] - jacobian[i][j]) / finiteDifferencesJacobian[i][j]); if (j < 3) { errorsP[indexP++] = relativeError; } else { errorsV[indexV++] = relativeError; } } } } // median errors Assert.assertEquals(0.0, new Median().evaluate(errorsP), 2.1e-10); Assert.assertEquals(0.0, new Median().evaluate(errorsV), 2.1e-10); } }