use of org.orekit.estimation.measurements.ObservedMeasurement in project Orekit by CS-SI.
the class KalmanOrbitDeterminationTest method run.
/**
* Function running the Kalman filter estimation.
* @param input Input configuration file
* @param orbitType Orbit type to use (calculation and display)
* @param print Choose whether the results are printed on console or not
* @param cartesianOrbitalP Orbital part of the initial covariance matrix in Cartesian formalism
* @param cartesianOrbitalQ Orbital part of the process noise matrix in Cartesian formalism
* @param propagationP Propagation part of the initial covariance matrix
* @param propagationQ Propagation part of the process noise matrix
* @param measurementP Measurement part of the initial covariance matrix
* @param measurementQ Measurement part of the process noise matrix
*/
private ResultKalman run(final File input, final OrbitType orbitType, final boolean print, final RealMatrix cartesianOrbitalP, final RealMatrix cartesianOrbitalQ, final RealMatrix propagationP, final RealMatrix propagationQ, final RealMatrix measurementP, final RealMatrix measurementQ) throws IOException, IllegalArgumentException, OrekitException, ParseException {
// Read input parameters
KeyValueFileParser<ParameterKey> parser = new KeyValueFileParser<ParameterKey>(ParameterKey.class);
parser.parseInput(input.getAbsolutePath(), new FileInputStream(input));
// Log files
final RangeLog rangeLog = new RangeLog();
final RangeRateLog rangeRateLog = new RangeRateLog();
final AzimuthLog azimuthLog = new AzimuthLog();
final ElevationLog elevationLog = new ElevationLog();
final PositionLog positionLog = new PositionLog();
final VelocityLog velocityLog = new VelocityLog();
// Gravity field
GravityFieldFactory.addPotentialCoefficientsReader(new ICGEMFormatReader("eigen-5c.gfc", true));
final NormalizedSphericalHarmonicsProvider gravityField = createGravityField(parser);
// Orbit initial guess
Orbit initialGuess = createOrbit(parser, gravityField.getMu());
// Convert to desired orbit type
initialGuess = orbitType.convertType(initialGuess);
// IERS conventions
final IERSConventions conventions;
if (!parser.containsKey(ParameterKey.IERS_CONVENTIONS)) {
conventions = IERSConventions.IERS_2010;
} else {
conventions = IERSConventions.valueOf("IERS_" + parser.getInt(ParameterKey.IERS_CONVENTIONS));
}
// Central body
final OneAxisEllipsoid body = createBody(parser);
// Propagator builder
final NumericalPropagatorBuilder propagatorBuilder = createPropagatorBuilder(parser, conventions, gravityField, body, initialGuess);
// Measurements
final List<ObservedMeasurement<?>> measurements = new ArrayList<ObservedMeasurement<?>>();
for (final String fileName : parser.getStringsList(ParameterKey.MEASUREMENTS_FILES, ',')) {
measurements.addAll(readMeasurements(new File(input.getParentFile(), fileName), createStationsData(parser, body), createPVData(parser), createSatRangeBias(parser), createWeights(parser), createRangeOutliersManager(parser), createRangeRateOutliersManager(parser), createAzElOutliersManager(parser), createPVOutliersManager(parser)));
}
// Building the Kalman filter:
// - Gather the estimated measurement parameters in a list
// - Prepare the initial covariance matrix and the process noise matrix
// - Build the Kalman filter
// --------------------------------------------------------------------
// Build the list of estimated measurements
final ParameterDriversList estimatedMeasurementsParameters = new ParameterDriversList();
for (ObservedMeasurement<?> measurement : measurements) {
final List<ParameterDriver> drivers = measurement.getParametersDrivers();
for (ParameterDriver driver : drivers) {
if (driver.isSelected()) {
// Add the driver
estimatedMeasurementsParameters.add(driver);
}
}
}
// Sort the list lexicographically
estimatedMeasurementsParameters.sort();
// Orbital covariance matrix initialization
// Jacobian of the orbital parameters w/r to Cartesian
final double[][] dYdC = new double[6][6];
initialGuess.getJacobianWrtCartesian(propagatorBuilder.getPositionAngle(), dYdC);
final RealMatrix Jac = MatrixUtils.createRealMatrix(dYdC);
RealMatrix orbitalP = Jac.multiply(cartesianOrbitalP.multiply(Jac.transpose()));
// Orbital process noise matrix
RealMatrix orbitalQ = Jac.multiply(cartesianOrbitalQ.multiply(Jac.transpose()));
// Build the full covariance matrix and process noise matrix
final int nbPropag = (propagationP != null) ? propagationP.getRowDimension() : 0;
final int nbMeas = (measurementP != null) ? measurementP.getRowDimension() : 0;
final RealMatrix initialP = MatrixUtils.createRealMatrix(6 + nbPropag + nbMeas, 6 + nbPropag + nbMeas);
final RealMatrix Q = MatrixUtils.createRealMatrix(6 + nbPropag + nbMeas, 6 + nbPropag + nbMeas);
// Orbital part
initialP.setSubMatrix(orbitalP.getData(), 0, 0);
Q.setSubMatrix(orbitalQ.getData(), 0, 0);
// Propagation part
if (propagationP != null) {
initialP.setSubMatrix(propagationP.getData(), 6, 6);
Q.setSubMatrix(propagationQ.getData(), 6, 6);
}
// Measurement part
if (measurementP != null) {
initialP.setSubMatrix(measurementP.getData(), 6 + nbPropag, 6 + nbPropag);
Q.setSubMatrix(measurementQ.getData(), 6 + nbPropag, 6 + nbPropag);
}
// Build the Kalman
KalmanEstimatorBuilder kalmanBuilder = new KalmanEstimatorBuilder();
kalmanBuilder.builder(propagatorBuilder);
kalmanBuilder.estimatedMeasurementsParameters(estimatedMeasurementsParameters);
kalmanBuilder.initialCovarianceMatrix(initialP);
kalmanBuilder.processNoiseMatrixProvider(new ConstantProcessNoise(Q));
final KalmanEstimator kalman = kalmanBuilder.build();
// Add an observer
kalman.setObserver(new KalmanObserver() {
/**
* Date of the first measurement.
*/
private AbsoluteDate t0;
/**
* {@inheritDoc}
* @throws OrekitException
*/
@Override
@SuppressWarnings("unchecked")
public void evaluationPerformed(final KalmanEstimation estimation) throws OrekitException {
// Current measurement number, date and status
final EstimatedMeasurement<?> estimatedMeasurement = estimation.getCorrectedMeasurement();
final int currentNumber = estimation.getCurrentMeasurementNumber();
final AbsoluteDate currentDate = estimatedMeasurement.getDate();
final EstimatedMeasurement.Status currentStatus = estimatedMeasurement.getStatus();
// Current estimated measurement
final ObservedMeasurement<?> observedMeasurement = estimatedMeasurement.getObservedMeasurement();
// Measurement type & Station name
String measType = "";
String stationName = "";
// Register the measurement in the proper measurement logger
if (observedMeasurement instanceof Range) {
// Add the tuple (estimation, prediction) to the log
rangeLog.add(currentNumber, (EstimatedMeasurement<Range>) estimatedMeasurement);
// Measurement type & Station name
measType = "RANGE";
stationName = ((EstimatedMeasurement<Range>) estimatedMeasurement).getObservedMeasurement().getStation().getBaseFrame().getName();
} else if (observedMeasurement instanceof RangeRate) {
rangeRateLog.add(currentNumber, (EstimatedMeasurement<RangeRate>) estimatedMeasurement);
measType = "RANGE_RATE";
stationName = ((EstimatedMeasurement<RangeRate>) estimatedMeasurement).getObservedMeasurement().getStation().getBaseFrame().getName();
} else if (observedMeasurement instanceof AngularAzEl) {
azimuthLog.add(currentNumber, (EstimatedMeasurement<AngularAzEl>) estimatedMeasurement);
elevationLog.add(currentNumber, (EstimatedMeasurement<AngularAzEl>) estimatedMeasurement);
measType = "AZ_EL";
stationName = ((EstimatedMeasurement<AngularAzEl>) estimatedMeasurement).getObservedMeasurement().getStation().getBaseFrame().getName();
} else if (observedMeasurement instanceof PV) {
positionLog.add(currentNumber, (EstimatedMeasurement<PV>) estimatedMeasurement);
velocityLog.add(currentNumber, (EstimatedMeasurement<PV>) estimatedMeasurement);
measType = "PV";
}
// Header
if (print) {
if (currentNumber == 1) {
// Set t0 to first measurement date
t0 = currentDate;
// Print header
final String formatHeader = "%-4s\t%-25s\t%15s\t%-10s\t%-10s\t%-20s\t%20s\t%20s";
String header = String.format(Locale.US, formatHeader, "Nb", "Epoch", "Dt[s]", "Status", "Type", "Station", "DP Corr", "DV Corr");
// Orbital drivers
for (DelegatingDriver driver : estimation.getEstimatedOrbitalParameters().getDrivers()) {
header += String.format(Locale.US, "\t%20s", driver.getName());
header += String.format(Locale.US, "\t%20s", "D" + driver.getName());
}
// Propagation drivers
for (DelegatingDriver driver : estimation.getEstimatedPropagationParameters().getDrivers()) {
header += String.format(Locale.US, "\t%20s", driver.getName());
header += String.format(Locale.US, "\t%20s", "D" + driver.getName());
}
// Measurements drivers
for (DelegatingDriver driver : estimation.getEstimatedMeasurementsParameters().getDrivers()) {
header += String.format(Locale.US, "\t%20s", driver.getName());
header += String.format(Locale.US, "\t%20s", "D" + driver.getName());
}
// Print header
System.out.println(header);
}
// Print current measurement info in terminal
String line = "";
// Line format
final String lineFormat = "%4d\t%-25s\t%15.3f\t%-10s\t%-10s\t%-20s\t%20.9e\t%20.9e";
// Orbital correction = DP & DV between predicted orbit and estimated orbit
final Vector3D predictedP = estimation.getPredictedSpacecraftStates()[0].getPVCoordinates().getPosition();
final Vector3D predictedV = estimation.getPredictedSpacecraftStates()[0].getPVCoordinates().getVelocity();
final Vector3D estimatedP = estimation.getCorrectedSpacecraftStates()[0].getPVCoordinates().getPosition();
final Vector3D estimatedV = estimation.getCorrectedSpacecraftStates()[0].getPVCoordinates().getVelocity();
final double DPcorr = Vector3D.distance(predictedP, estimatedP);
final double DVcorr = Vector3D.distance(predictedV, estimatedV);
line = String.format(Locale.US, lineFormat, currentNumber, currentDate.toString(), currentDate.durationFrom(t0), currentStatus.toString(), measType, stationName, DPcorr, DVcorr);
// Handle parameters printing (value and error)
int jPar = 0;
final RealMatrix Pest = estimation.getPhysicalEstimatedCovarianceMatrix();
// Orbital drivers
for (DelegatingDriver driver : estimation.getEstimatedOrbitalParameters().getDrivers()) {
line += String.format(Locale.US, "\t%20.9f", driver.getValue());
line += String.format(Locale.US, "\t%20.9e", FastMath.sqrt(Pest.getEntry(jPar, jPar)));
jPar++;
}
// Propagation drivers
for (DelegatingDriver driver : estimation.getEstimatedPropagationParameters().getDrivers()) {
line += String.format(Locale.US, "\t%20.9f", driver.getValue());
line += String.format(Locale.US, "\t%20.9e", FastMath.sqrt(Pest.getEntry(jPar, jPar)));
jPar++;
}
// Measurements drivers
for (DelegatingDriver driver : estimatedMeasurementsParameters.getDrivers()) {
line += String.format(Locale.US, "\t%20.9f", driver.getValue());
line += String.format(Locale.US, "\t%20.9e", FastMath.sqrt(Pest.getEntry(jPar, jPar)));
jPar++;
}
// Print the line
System.out.println(line);
}
}
});
// Process the list measurements
final Orbit estimated = kalman.processMeasurements(measurements).getInitialState().getOrbit();
// Get the last estimated physical covariances
final RealMatrix covarianceMatrix = kalman.getPhysicalEstimatedCovarianceMatrix();
// Parameters and measurements.
final ParameterDriversList propagationParameters = kalman.getPropagationParametersDrivers(true);
final ParameterDriversList measurementsParameters = kalman.getEstimatedMeasurementsParameters();
// Eventually, print parameter changes, statistics and covariances
if (print) {
// Display parameter change for non orbital drivers
int length = 0;
for (final ParameterDriver parameterDriver : propagationParameters.getDrivers()) {
length = FastMath.max(length, parameterDriver.getName().length());
}
for (final ParameterDriver parameterDriver : measurementsParameters.getDrivers()) {
length = FastMath.max(length, parameterDriver.getName().length());
}
if (propagationParameters.getNbParams() > 0) {
displayParametersChanges(System.out, "Estimated propagator parameters changes: ", true, length, propagationParameters);
}
if (measurementsParameters.getNbParams() > 0) {
displayParametersChanges(System.out, "Estimated measurements parameters changes: ", true, length, measurementsParameters);
}
// Measurements statistics summary
System.out.println("");
rangeLog.displaySummary(System.out);
rangeRateLog.displaySummary(System.out);
azimuthLog.displaySummary(System.out);
elevationLog.displaySummary(System.out);
positionLog.displaySummary(System.out);
velocityLog.displaySummary(System.out);
// Covariances and sigmas
displayFinalCovariances(System.out, kalman);
}
// Instantiation of the results
return new ResultKalman(propagationParameters, measurementsParameters, kalman.getCurrentMeasurementNumber(), estimated.getPVCoordinates(), rangeLog.createStatisticsSummary(), rangeRateLog.createStatisticsSummary(), azimuthLog.createStatisticsSummary(), elevationLog.createStatisticsSummary(), positionLog.createStatisticsSummary(), velocityLog.createStatisticsSummary(), covarianceMatrix);
}
use of org.orekit.estimation.measurements.ObservedMeasurement in project Orekit by CS-SI.
the class BatchLSEstimatorTest method testKeplerRange.
/**
* Perfect range measurements with a biased start
* @throws OrekitException
*/
@Test
public void testKeplerRange() throws OrekitException {
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 range measurements
final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit, propagatorBuilder);
final List<ObservedMeasurement<?>> measurements = EstimationTestUtils.createMeasurements(propagator, new RangeMeasurementCreator(context), 1.0, 3.0, 300.0);
// create orbit estimator
final BatchLSEstimator estimator = new BatchLSEstimator(new LevenbergMarquardtOptimizer(), propagatorBuilder);
for (final ObservedMeasurement<?> range : measurements) {
estimator.addMeasurement(range);
}
estimator.setParametersConvergenceThreshold(1.0e-2);
estimator.setMaxIterations(10);
estimator.setMaxEvaluations(20);
estimator.setObserver(new BatchLSObserver() {
int lastIter = 0;
int lastEval = 0;
/**
* {@inheritDoc}
*/
@Override
public void evaluationPerformed(int iterationsCount, int evaluationscount, Orbit[] orbits, ParameterDriversList estimatedOrbitalParameters, ParameterDriversList estimatedPropagatorParameters, ParameterDriversList estimatedMeasurementsParameters, EstimationsProvider evaluationsProvider, Evaluation lspEvaluation) throws OrekitException {
if (iterationsCount == lastIter) {
Assert.assertEquals(lastEval + 1, evaluationscount);
} else {
Assert.assertEquals(lastIter + 1, iterationsCount);
}
lastIter = iterationsCount;
lastEval = evaluationscount;
Assert.assertEquals(measurements.size(), evaluationsProvider.getNumber());
try {
evaluationsProvider.getEstimatedMeasurement(-1);
Assert.fail("an exception should have been thrown");
} catch (OrekitException oe) {
Assert.assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE, oe.getSpecifier());
}
try {
evaluationsProvider.getEstimatedMeasurement(measurements.size());
Assert.fail("an exception should have been thrown");
} catch (OrekitException oe) {
Assert.assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE, oe.getSpecifier());
}
AbsoluteDate previous = AbsoluteDate.PAST_INFINITY;
for (int i = 0; i < evaluationsProvider.getNumber(); ++i) {
AbsoluteDate current = evaluationsProvider.getEstimatedMeasurement(i).getDate();
Assert.assertTrue(current.compareTo(previous) >= 0);
previous = current;
}
}
});
ParameterDriver aDriver = estimator.getOrbitalParametersDrivers(true).getDrivers().get(0);
Assert.assertEquals("a", aDriver.getName());
aDriver.setValue(aDriver.getValue() + 1.2);
aDriver.setReferenceDate(AbsoluteDate.GALILEO_EPOCH);
EstimationTestUtils.checkFit(context, estimator, 2, 3, 0.0, 1.1e-6, 0.0, 2.8e-6, 0.0, 4.0e-7, 0.0, 2.2e-10);
// got a default one
for (final ParameterDriver driver : estimator.getOrbitalParametersDrivers(true).getDrivers()) {
if ("a".equals(driver.getName())) {
// user-specified reference date
Assert.assertEquals(0, driver.getReferenceDate().durationFrom(AbsoluteDate.GALILEO_EPOCH), 1.0e-15);
} else {
// default reference date
Assert.assertEquals(0, driver.getReferenceDate().durationFrom(propagatorBuilder.getInitialOrbitDate()), 1.0e-15);
}
}
}
use of org.orekit.estimation.measurements.ObservedMeasurement in project Orekit by CS-SI.
the class ModelTest method testPerfectValue.
@Test
public void testPerfectValue() throws OrekitException {
final Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
final NumericalPropagatorBuilder propagatorBuilder = context.createBuilder(OrbitType.KEPLERIAN, PositionAngle.TRUE, true, 1.0e-6, 60.0, 0.001);
final NumericalPropagatorBuilder[] builders = { propagatorBuilder };
// 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);
final ParameterDriversList estimatedMeasurementsParameters = new ParameterDriversList();
for (ObservedMeasurement<?> measurement : measurements) {
for (final ParameterDriver driver : measurement.getParametersDrivers()) {
if (driver.isSelected()) {
estimatedMeasurementsParameters.add(driver);
}
}
}
// create model
final ModelObserver modelObserver = new ModelObserver() {
/**
* {@inheritDoc}
*/
@Override
public void modelCalled(final Orbit[] newOrbits, final Map<ObservedMeasurement<?>, EstimatedMeasurement<?>> newEvaluations) {
Assert.assertEquals(1, newOrbits.length);
Assert.assertEquals(0, context.initialOrbit.getDate().durationFrom(newOrbits[0].getDate()), 1.0e-15);
Assert.assertEquals(0, Vector3D.distance(context.initialOrbit.getPVCoordinates().getPosition(), newOrbits[0].getPVCoordinates().getPosition()), 1.0e-15);
Assert.assertEquals(measurements.size(), newEvaluations.size());
}
};
final Model model = new Model(builders, measurements, estimatedMeasurementsParameters, modelObserver);
model.setIterationsCounter(new Incrementor(100));
model.setEvaluationsCounter(new Incrementor(100));
// Test forward propagation flag to true
assertEquals(true, model.isForwardPropagation());
// evaluate model on perfect start point
final double[] normalizedProp = propagatorBuilder.getSelectedNormalizedParameters();
final double[] normalized = new double[normalizedProp.length + estimatedMeasurementsParameters.getNbParams()];
System.arraycopy(normalizedProp, 0, normalized, 0, normalizedProp.length);
int i = normalizedProp.length;
for (final ParameterDriver driver : estimatedMeasurementsParameters.getDrivers()) {
normalized[i++] = driver.getNormalizedValue();
}
Pair<RealVector, RealMatrix> value = model.value(new ArrayRealVector(normalized));
int index = 0;
for (ObservedMeasurement<?> measurement : measurements) {
for (int k = 0; k < measurement.getDimension(); ++k) {
// the value is already a weighted residual
Assert.assertEquals(0.0, value.getFirst().getEntry(index++), 1.6e-7);
}
}
Assert.assertEquals(index, value.getFirst().getDimension());
}
use of org.orekit.estimation.measurements.ObservedMeasurement in project Orekit by CS-SI.
the class OrbitDeterminationTest method readMeasurements.
/**
* Read a measurements file.
* @param file measurements file
* @param stations name to stations data map
* @param pvData PV measurements data
* @param satRangeBias range bias due to transponder delay
* @param weights base weights for measurements
* @param rangeOutliersManager manager for range measurements outliers (null if none configured)
* @param rangeRateOutliersManager manager for range-rate measurements outliers (null if none configured)
* @param azElOutliersManager manager for azimuth-elevation measurements outliers (null if none configured)
* @param pvOutliersManager manager for PV measurements outliers (null if none configured)
* @return measurements list
*/
private List<ObservedMeasurement<?>> readMeasurements(final File file, final Map<String, StationData> stations, final PVData pvData, final Bias<Range> satRangeBias, final Weights weights, final OutlierFilter<Range> rangeOutliersManager, final OutlierFilter<RangeRate> rangeRateOutliersManager, final OutlierFilter<AngularAzEl> azElOutliersManager, final OutlierFilter<PV> pvOutliersManager) throws UnsupportedEncodingException, IOException, OrekitException {
final List<ObservedMeasurement<?>> measurements = new ArrayList<ObservedMeasurement<?>>();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
int lineNumber = 0;
for (String line = br.readLine(); line != null; line = br.readLine()) {
++lineNumber;
line = line.trim();
if (line.length() > 0 && !line.startsWith("#")) {
String[] fields = line.split("\\s+");
if (fields.length < 2) {
throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, lineNumber, file.getName(), line);
}
switch(fields[1]) {
case "RANGE":
final Range range = new RangeParser().parseFields(fields, stations, pvData, satRangeBias, weights, line, lineNumber, file.getName());
if (rangeOutliersManager != null) {
range.addModifier(rangeOutliersManager);
}
addIfNonZeroWeight(range, measurements);
break;
case "RANGE_RATE":
final RangeRate rangeRate = new RangeRateParser().parseFields(fields, stations, pvData, satRangeBias, weights, line, lineNumber, file.getName());
if (rangeOutliersManager != null) {
rangeRate.addModifier(rangeRateOutliersManager);
}
addIfNonZeroWeight(rangeRate, measurements);
break;
case "AZ_EL":
final AngularAzEl angular = new AzElParser().parseFields(fields, stations, pvData, satRangeBias, weights, line, lineNumber, file.getName());
if (azElOutliersManager != null) {
angular.addModifier(azElOutliersManager);
}
addIfNonZeroWeight(angular, measurements);
break;
case "PV":
final PV pv = new PVParser().parseFields(fields, stations, pvData, satRangeBias, weights, line, lineNumber, file.getName());
if (pvOutliersManager != null) {
pv.addModifier(pvOutliersManager);
}
addIfNonZeroWeight(pv, measurements);
break;
default:
throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE, "unknown measurement type " + fields[1] + " at line " + lineNumber + " in file " + file.getName());
}
}
}
} finally {
if (br != null) {
br.close();
}
}
if (measurements.isEmpty()) {
throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE, "not measurements read from file " + file.getAbsolutePath());
}
return measurements;
}
use of org.orekit.estimation.measurements.ObservedMeasurement in project Orekit by CS-SI.
the class BiasTest method testEstimateBias.
@SuppressWarnings("unchecked")
@Test
public void testEstimateBias() throws OrekitException {
Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
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 RangeMeasurementCreator(context), 1.0, 3.0, 300.0);
// create range biases: one bias for each station
final RandomGenerator random = new Well19937a(0x0c4b69da5d64b35al);
final Bias<?>[] stationsRangeBiases = new Bias<?>[context.stations.size()];
final double[] realStationsBiases = new double[context.stations.size()];
for (int i = 0; i < context.stations.size(); ++i) {
final TopocentricFrame base = context.stations.get(i).getBaseFrame();
stationsRangeBiases[i] = new Bias<Range>(new String[] { base.getName() + " range bias" }, new double[] { 0.0 }, new double[] { 1.0 }, new double[] { Double.NEGATIVE_INFINITY }, new double[] { Double.POSITIVE_INFINITY });
realStationsBiases[i] = 2 * random.nextDouble() - 1;
}
// create orbit estimator
final BatchLSEstimator estimator = new BatchLSEstimator(new LevenbergMarquardtOptimizer(), propagatorBuilder);
// add the measurements, with both spacecraft and stations biases
for (final ObservedMeasurement<?> measurement : measurements) {
final Range range = (Range) measurement;
for (int i = 0; i < context.stations.size(); ++i) {
if (range.getStation() == context.stations.get(i)) {
double biasedRange = range.getObservedValue()[0] + realStationsBiases[i];
final Range m = new Range(range.getStation(), range.getDate(), biasedRange, range.getTheoreticalStandardDeviation()[0], range.getBaseWeight()[0]);
m.addModifier((Bias<Range>) stationsRangeBiases[i]);
estimator.addMeasurement(m);
}
}
}
estimator.setParametersConvergenceThreshold(1.0e-3);
estimator.setMaxIterations(10);
estimator.setMaxEvaluations(20);
// we want to estimate the biases
for (Bias<?> bias : stationsRangeBiases) {
for (final ParameterDriver driver : bias.getParametersDrivers()) {
driver.setSelected(true);
}
}
EstimationTestUtils.checkFit(context, estimator, 2, 3, 0.0, 7.2e-7, 0.0, 2.1e-6, 0.0, 3.7e-7, 0.0, 1.7e-10);
for (int i = 0; i < stationsRangeBiases.length; ++i) {
Assert.assertEquals(realStationsBiases[i], stationsRangeBiases[i].getParametersDrivers().get(0).getValue(), 3.3e-6);
}
}
Aggregations