use of org.orekit.utils.ParameterDriver in project Orekit by CS-SI.
the class BatchLSEstimator method estimate.
/**
* Estimate the orbital, propagation and measurements parameters.
* <p>
* The initial guess for all parameters must have been set before calling this method
* using {@link #getOrbitalParametersDrivers(boolean)}, {@link #getPropagatorParametersDrivers(boolean)},
* and {@link #getMeasurementsParametersDrivers(boolean)} and then {@link ParameterDriver#setValue(double)
* setting the values} of the parameters.
* </p>
* <p>
* For parameters whose reference date has not been set to a non-null date beforehand (i.e.
* the parameters for which {@link ParameterDriver#getReferenceDate()} returns {@code null},
* a default reference date will be set automatically at the start of the estimation to the
* {@link NumericalPropagatorBuilder#getInitialOrbitDate() initial orbit date} of the first
* propagator builder. For parameters whose reference date has been set to a non-null date,
* this reference date is untouched.
* </p>
* <p>
* After this method returns, the estimated parameters can be retrieved using
* {@link #getOrbitalParametersDrivers(boolean)}, {@link #getPropagatorParametersDrivers(boolean)},
* and {@link #getMeasurementsParametersDrivers(boolean)} and then {@link ParameterDriver#getValue()
* getting the values} of the parameters.
* </p>
* <p>
* As a convenience, the method also returns a fully configured and ready to use
* propagator set up with all the estimated values.
* </p>
* <p>
* For even more in-depth information, the {@link #getOptimum()} method provides detailed
* elements (covariance matrix, estimated parameters standard deviation, weighted Jacobian, RMS,
* χ², residuals and more).
* </p>
* @return propagators configured with estimated orbits as initial states, and all
* propagators estimated parameters also set
* @exception OrekitException if there is a conflict in parameters names
* or if orbit cannot be determined
*/
public NumericalPropagator[] estimate() throws OrekitException {
// set reference date for all parameters that lack one (including the not estimated parameters)
for (final ParameterDriver driver : getOrbitalParametersDrivers(false).getDrivers()) {
if (driver.getReferenceDate() == null) {
driver.setReferenceDate(builders[0].getInitialOrbitDate());
}
}
for (final ParameterDriver driver : getPropagatorParametersDrivers(false).getDrivers()) {
if (driver.getReferenceDate() == null) {
driver.setReferenceDate(builders[0].getInitialOrbitDate());
}
}
for (final ParameterDriver driver : getMeasurementsParametersDrivers(false).getDrivers()) {
if (driver.getReferenceDate() == null) {
driver.setReferenceDate(builders[0].getInitialOrbitDate());
}
}
// get all estimated parameters
final ParameterDriversList estimatedOrbitalParameters = getOrbitalParametersDrivers(true);
final ParameterDriversList estimatedPropagatorParameters = getPropagatorParametersDrivers(true);
final ParameterDriversList estimatedMeasurementsParameters = getMeasurementsParametersDrivers(true);
// create start point
final double[] start = new double[estimatedOrbitalParameters.getNbParams() + estimatedPropagatorParameters.getNbParams() + estimatedMeasurementsParameters.getNbParams()];
int iStart = 0;
for (final ParameterDriver driver : estimatedOrbitalParameters.getDrivers()) {
start[iStart++] = driver.getNormalizedValue();
}
for (final ParameterDriver driver : estimatedPropagatorParameters.getDrivers()) {
start[iStart++] = driver.getNormalizedValue();
}
for (final ParameterDriver driver : estimatedMeasurementsParameters.getDrivers()) {
start[iStart++] = driver.getNormalizedValue();
}
lsBuilder.start(start);
// create target (which is an array set to 0, as we compute weighted residuals ourselves)
int p = 0;
for (final ObservedMeasurement<?> measurement : measurements) {
if (measurement.isEnabled()) {
p += measurement.getDimension();
}
}
final double[] target = new double[p];
lsBuilder.target(target);
// set up the model
final ModelObserver modelObserver = new ModelObserver() {
/**
* {@inheritDoc}
*/
@Override
public void modelCalled(final Orbit[] newOrbits, final Map<ObservedMeasurement<?>, EstimatedMeasurement<?>> newEstimations) {
BatchLSEstimator.this.orbits = newOrbits;
BatchLSEstimator.this.estimations = newEstimations;
}
};
final Model model = new Model(builders, measurements, estimatedMeasurementsParameters, modelObserver);
lsBuilder.model(model);
// add a validator for orbital parameters
lsBuilder.parameterValidator(new Validator(estimatedOrbitalParameters, estimatedPropagatorParameters, estimatedMeasurementsParameters));
lsBuilder.checker(new ConvergenceChecker<LeastSquaresProblem.Evaluation>() {
/**
* {@inheritDoc}
*/
@Override
public boolean converged(final int iteration, final LeastSquaresProblem.Evaluation previous, final LeastSquaresProblem.Evaluation current) {
final double lInf = current.getPoint().getLInfDistance(previous.getPoint());
return lInf <= parametersConvergenceThreshold;
}
});
// set up the problem to solve
final LeastSquaresProblem problem = new TappedLSProblem(lsBuilder.build(), model, estimatedOrbitalParameters, estimatedPropagatorParameters, estimatedMeasurementsParameters);
try {
// solve the problem
optimum = optimizer.optimize(problem);
// create a new configured propagator with all estimated parameters
return model.createPropagators(optimum.getPoint());
} catch (MathRuntimeException mrte) {
throw new OrekitException(mrte);
} catch (OrekitExceptionWrapper oew) {
throw oew.getException();
}
}
use of org.orekit.utils.ParameterDriver in project Orekit by CS-SI.
the class RangeTroposphericDelayModifier method modify.
/**
* {@inheritDoc}
*/
@Override
public void modify(final EstimatedMeasurement<Range> estimated) throws OrekitException {
final Range measurement = estimated.getObservedMeasurement();
final GroundStation station = measurement.getStation();
final SpacecraftState state = estimated.getStates()[0];
final double[] oldValue = estimated.getEstimatedValue();
final double delay = rangeErrorTroposphericModel(station, state);
// update estimated value taking into account the tropospheric delay.
// The tropospheric delay is directly added to the range.
final double[] newValue = oldValue.clone();
newValue[0] = newValue[0] + delay;
estimated.setEstimatedValue(newValue);
// update estimated derivatives with Jacobian of the measure wrt state
final double[][] djac = rangeErrorJacobianState(station, state);
final double[][] stateDerivatives = estimated.getStateDerivatives(0);
for (int irow = 0; irow < stateDerivatives.length; ++irow) {
for (int jcol = 0; jcol < stateDerivatives[0].length; ++jcol) {
stateDerivatives[irow][jcol] += djac[irow][jcol];
}
}
estimated.setStateDerivatives(0, stateDerivatives);
for (final ParameterDriver driver : Arrays.asList(station.getEastOffsetDriver(), station.getNorthOffsetDriver(), station.getZenithOffsetDriver())) {
if (driver.isSelected()) {
// update estimated derivatives with derivative of the modification wrt station parameters
double parameterDerivative = estimated.getParameterDerivatives(driver)[0];
parameterDerivative += rangeErrorParameterDerivative(station, driver, state, delay);
estimated.setParameterDerivatives(driver, parameterDerivative);
}
}
}
use of org.orekit.utils.ParameterDriver in project Orekit by CS-SI.
the class TurnAroundRangeTroposphericDelayModifier method rangeErrorParameterDerivative.
/**
* Compute the derivative of the delay term wrt parameters.
*
* @param station ground station
* @param driver driver for the station offset parameter
* @param state spacecraft state
* @return derivative of the delay wrt station offset parameter
* @throws OrekitException if frames transformations cannot be computed
*/
private double rangeErrorParameterDerivative(final GroundStation station, final ParameterDriver driver, final SpacecraftState state) throws OrekitException {
final ParameterFunction rangeError = new ParameterFunction() {
/**
* {@inheritDoc}
*/
@Override
public double value(final ParameterDriver parameterDriver) throws OrekitException {
return rangeErrorTroposphericModel(station, state);
}
};
final ParameterFunction rangeErrorDerivative = Differentiation.differentiate(rangeError, driver, 3, 10.0);
return rangeErrorDerivative.value(driver);
}
use of org.orekit.utils.ParameterDriver in project Orekit by CS-SI.
the class FiniteDifferencePropagatorConverterTest method testGetObjectiveFunctionParametersOnlyScaledOnce.
/**
* Test case for bug #362. Check that scaling is only applied once.
*
* @throws OrekitException on error.
*/
@Test
public void testGetObjectiveFunctionParametersOnlyScaledOnce() throws OrekitException {
// setup
// create some arbitrary sample data to run with
Frame eci = FramesFactory.getGCRF();
double gm = Constants.EIGEN5C_EARTH_MU;
AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
Propagator source = new KeplerianPropagator(new KeplerianOrbit(6878137, 0, 0, 0, 0, 0, PositionAngle.TRUE, eci, date, gm));
// Create a mock builder that allows us to check the values passed to it
PropagatorBuilder builder = Mockito.mock(PropagatorBuilder.class);
ParameterDriversList list = new ParameterDriversList();
list.add(new ParameterDriver("p1", 0, 1e-3, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
Mockito.when(builder.getOrbitalParametersDrivers()).thenReturn(list);
Mockito.when(builder.getPropagationParametersDrivers()).thenReturn(new ParameterDriversList());
Mockito.when(builder.getFrame()).thenReturn(eci);
Mockito.when(builder.getSelectedNormalizedParameters()).thenReturn(new double[1]);
Mockito.when(builder.buildPropagator(Mockito.any(double[].class))).thenReturn(source);
// subject under test
FiniteDifferencePropagatorConverter converter = new FiniteDifferencePropagatorConverter(builder, 1, 100);
// set some internal variables in FDPC that are not settable using another
// interface
converter.convert(source, 1, 2);
// Forget all the side effect of the call to convert()
Mockito.clearInvocations(builder);
// action
converter.getModel().value(new ArrayRealVector(1));
// verify
Mockito.verify(builder).buildPropagator(new double[] { 0 });
Mockito.verify(builder).buildPropagator(new double[] { 1 });
}
use of org.orekit.utils.ParameterDriver in project Orekit by CS-SI.
the class PartialDerivativesEquations method freezeParametersSelection.
/**
* Freeze the selected parameters from the force models.
* @exception OrekitException if an existing driver for a
* parameter throws one when its value is reset using the value
* from another driver managing the same parameter
*/
private void freezeParametersSelection() throws OrekitException {
if (selected == null) {
// first pass: gather all parameters, binding similar names together
selected = new ParameterDriversList();
for (final ForceModel provider : propagator.getAllForceModels()) {
for (final ParameterDriver driver : provider.getParametersDrivers()) {
selected.add(driver);
}
}
// second pass: now that shared parameter names are bound together,
// their selections status have been synchronized, we can filter them
selected.filter(true);
// third pass: sort parameters lexicographically
selected.sort();
// fourth pass: set up a map between parameters drivers and matrices columns
map = new IdentityHashMap<ParameterDriver, Integer>();
int parameterIndex = 0;
for (final ParameterDriver selectedDriver : selected.getDrivers()) {
for (final ForceModel provider : propagator.getAllForceModels()) {
for (final ParameterDriver driver : provider.getParametersDrivers()) {
if (driver.getName().equals(selectedDriver.getName())) {
map.put(driver, parameterIndex);
}
}
}
++parameterIndex;
}
}
}
Aggregations