Fixes #1203
Hello, I have noticed that this method is sorting the propagation drivers each time that the a driver is added :
protected void addSupportedParameter(final ParameterDriver driver) {
propagationDrivers.add(driver);
propagationDrivers.sort();
}
If we do a propagation with a lot of force models ( a lot of maneuvers for example), adding all the maneuvers to the propagatorBuilder takes more time than the propagation itself and it is is increasing exponentially with the number of maneuvers.
I think that there is a simple turnaround if we replace the method with addSupportedParameters(final List<ParameterDriver> drivers)
This issue is linked to the following topic in the forum : https://forum.orekit.org/t/issue-with-maneuver-date-estimation-propagator/2424.
to reproduce the issue you can try to retrieve the propagator at the end of the maneuver-estimation tutorial :
Propagator[] estimatedPropagators = estimator.estimate();
finish(estimatedPropagators);
Orbit estimated = estimatedPropagators[0].getInitialState().getOrbit();
estimatedPropagators[0].propagate(estimated.getDate().shiftedBy(12 * 3600));
The following error should occur :
org.orekit.errors.OrekitException: unknown additional state "org.orekit.estimation.leastsquares.BatchLSModel-derivatives"
turnarounds have been found on the forum.
It seems to be fine with our tests ! Thank you very much for the fix.
Hello! Here is the issue linked to the following discussion on the forum.
Lately, we have been encountering this error when trying to estimate only a selection of orbital parameters with the BatchLeastSquareEstimator :
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.get(ArrayList.java:433)
at java.util.Collections$UnmodifiableList.get(Collections.java:1309)
at org.orekit.estimation.leastsquares.AbstractBatchLSModel.fetchEvaluatedMeasurement(AbstractBatchLSModel.java:462)
at org.orekit.estimation.leastsquares.MeasurementHandler.handleStep(MeasurementHandler.java:94)
at org.orekit.propagation.PropagatorsParallelizer$SinglePropagatorHandler.handleStep(PropagatorsParallelizer.java:276)
at org.orekit.propagation.integration.AbstractIntegratedPropagator$AdaptedStepHandler.handleStep(AbstractIntegratedPropagator.java:958)
It happens when estimating only the semi-major axis for example. Here is the test that is inspired from the BatchLSEstimatorTest to reproduce this issue:
public void testEstimateOnlyOneOrbitalParameter() {
Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
final NumericalPropagatorBuilder propagatorBuilder =
context.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true,
1.0e-6, 60.0, 1.0);
// create perfect PV measurements
final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
propagatorBuilder);
final List<ObservedMeasurement<?>> measurements =
EstimationTestUtils.createMeasurements(propagator,
new PVMeasurementCreator(),
0.0, 1.0, 300.0);
// select only the first orbital parameter
boolean[] orbitalParametersEstimated = new boolean[]{true, false, false, false, false, false};
List<ParameterDriversList.DelegatingDriver> orbitalElementsDrivers = propagatorBuilder.getOrbitalParametersDrivers().getDrivers();
IntStream.range(0, orbitalParametersEstimated.length).forEach(i -> orbitalElementsDrivers.get(i).setSelected(orbitalParametersEstimated[i]));
//create the estimator
final BatchLSEstimator estimator = new BatchLSEstimator(new LevenbergMarquardtOptimizer(),
propagatorBuilder);
for (final ObservedMeasurement<?> measurement : measurements) {
estimator.addMeasurement(measurement);
}
estimator.setParametersConvergenceThreshold(1.0e-2);
estimator.setMaxIterations(10);
estimator.setMaxEvaluations(20);
estimator.estimate();
I was wondering if it comes not from line 462 of the class AbstractBatchLSModel class (fetchEvaluatedMeasurement method) :
for (int j = 0; j < dMdY0.getColumnDimension(); ++j) {
final ParameterDriver driver = selectedOrbitalDrivers.getDrivers().get(j);
(...)
}
dMdY0.getColumnDimension() seems to be always equals to 6, which is not necessarily the case of the number of selected orbital drivers.
Thank you very much for your help,
Have a good day!
Hello, I think that I found a bug in the ephemeris state provider after a numerical propagation with several additional equations which have more than one additional parameter. Indeed this function in the inner class LocalGenerator of the IntegratedEphemeris class combines all additional states and returns only the relevant part of the array.
public double[] getAdditionalState(final SpacecraftState state) {
// extract the part of the interpolated array corresponding to the additional state
final double[] combined = getInterpolatedState(state.getDate()).getSecondaryState(1);
return Arrays.copyOfRange(combined, index, index + dimension);
}
My concern is that the index is not correct if the previous additional state has a dimension greater than one. The result is that the additional states are mixed and incorrect when the state is retrieved from the ephemeris.
I think that changing these lines:
// set up providers to map the final elements of the model array to additional states
for (int i = 0; i < equations.length; ++i) {
addAdditionalStateProvider(new LocalGenerator(equations[i], i, dimensions[i]));
}
by these :
int currentIndex=0;
for (int i = 0; i < equations.length; ++i) {
addAdditionalStateProvider(new LocalGenerator(equations[i], currentIndex, dimensions[i]));
currentIndex+=dimensions[i];
}
}
solves the issue