diff --git a/src/tutorials/java/AffinagePleiades/AffinageRugged.java b/src/tutorials/java/AffinagePleiades/AffinageRugged.java index c1ba241675dee2f023c4e8af3ca8c8afdd485e43..8b3127d6ab5e890eaa9b10870f4133d2534ffdb1 100644 --- a/src/tutorials/java/AffinagePleiades/AffinageRugged.java +++ b/src/tutorials/java/AffinagePleiades/AffinageRugged.java @@ -19,6 +19,7 @@ package AffinagePleiades; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresOptimizer.Optimum; +import org.hipparchus.linear.RealVector; import java.io.File; import java.util.Locale; @@ -49,6 +50,8 @@ import org.orekit.utils.AngularDerivativesFilter; import org.orekit.utils.CartesianDerivativesFilter; import org.orekit.utils.PVCoordinates; + + /** * Parameter estimation context * @author Jonathan Guinet @@ -160,8 +163,11 @@ public class AffinageRugged { System.out.format(" **** Generate Measures **** %n"); MeasureGenerator measure = new MeasureGenerator(pleiadesViewingModel,rugged); - measure.CreateMeasure(1000, 1000); + int lineSampling = 1000; + int pixelSampling = 1000; + measure.CreateMeasure(lineSampling, pixelSampling); + System.out.format("nb TiePoints %d %n", measure.getMeasureCount()); System.out.format(" **** Reset Roll/Pitch **** %n"); rugged. getLineSensor(pleiadesViewingModel.getSensorName()). @@ -177,11 +183,19 @@ public class AffinageRugged { }); + System.out.format(" **** Initial Residuals **** %n"); + + + + LocalisationMetrics initlialResiduals = new LocalisationMetrics(measure.getMapping(),rugged); + System.out.format("residuals max : %3.6e mean %3.6e %n",initlialResiduals.getMaxResidual(),initlialResiduals.getMeanResidual()); + + System.out.format(" **** Start optimization **** %n"); // perform parameters estimation int maxIterations = 15; - double convergenceThreshold = 1.0e-9; + double convergenceThreshold = 1e-12; System.out.format("iterations max %d convergence threshold %3.6e \n",maxIterations, convergenceThreshold); @@ -189,7 +203,7 @@ public class AffinageRugged { Optimum optimum = rugged.estimateFreeParameters(Collections.singletonList(measure.getMapping()), maxIterations,convergenceThreshold); - System.out.format(" Optimization performed in %d interation \n",optimum.getEvaluations()); + System.out.format(" Optimization performed in %d iterations \n",optimum.getEvaluations()); // check estimated values double estimatedRoll = rugged.getLineSensor(pleiadesViewingModel.getSensorName()). @@ -206,6 +220,19 @@ public class AffinageRugged { double pitchError = (estimatedPitch - pitchValue); System.out.format("Estimated pitch %3.5f pitch error %3.6e %n ", estimatedPitch, pitchError); + System.out.format(" **** Estimated Measures **** %n"); + + MeasureGenerator estimatedMeasure = new MeasureGenerator(pleiadesViewingModel,rugged); + estimatedMeasure.CreateMeasure(lineSampling, pixelSampling); + + System.out.format(" **** Compute Statistics **** %n"); + + LocalisationMetrics localisationResiduals = new LocalisationMetrics(measure.getMapping(),rugged); + System.out.format("residuals max : %3.6e mean %3.6e %n",localisationResiduals.getMaxResidual(),localisationResiduals.getMeanResidual()); + //RealVector residuals = optimum.getResiduals(); + + + } catch (OrekitException oe) { diff --git a/src/tutorials/java/AffinagePleiades/LocalisationMetrics.java b/src/tutorials/java/AffinagePleiades/LocalisationMetrics.java new file mode 100644 index 0000000000000000000000000000000000000000..0b8f2f47183e3f6b29902a9733ff7c5116a2f8bf --- /dev/null +++ b/src/tutorials/java/AffinagePleiades/LocalisationMetrics.java @@ -0,0 +1,157 @@ +/* Copyright 2013-2016 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 AffinagePleiades; + + + +import org.hipparchus.linear.ArrayRealVector; +import org.hipparchus.linear.RealVector; + +import org.orekit.rugged.api.SensorToGroundMapping; +import org.orekit.rugged.api.Rugged; +import org.orekit.rugged.linesensor.LineSensor; +import org.orekit.rugged.linesensor.SensorPixel; +import org.orekit.rugged.errors.RuggedException; +import org.orekit.time.AbsoluteDate; + +import java.util.Collections; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.Iterator; +import java.util.Locale; + +import org.hipparchus.util.FastMath; +import org.orekit.bodies.GeodeticPoint; + +/** class for measure generation + * @author Jonathan Guinet + */ +public class LocalisationMetrics { + + + /** mapping */ + private Set <Map.Entry<SensorPixel, GeodeticPoint>> groundTruthMappings; + + private Set <Map.Entry<SensorPixel, GeodeticPoint>> estimationMappings; + + private Rugged rugged; + + private LineSensor sensor; + + private PleiadesViewingModel viewingModel; + + private int measureCount; + + + /* max residual distance */ + private double resMax; + + + /* mean residual distance */ + private double resMean; + + + /** Simple constructor. + * <p> + * + * </p> + */ + public LocalisationMetrics(SensorToGroundMapping groundTruthMapping, Rugged rugged) throws RuggedException + { + + + groundTruthMappings = groundTruthMapping.getMappings(); + this.rugged = rugged; + this.sensor = rugged.getLineSensor(groundTruthMapping.getSensorName()); + this.computeMetrics(); + + } + + + /** Get the maximum residual; + * @return max residual + */ + public double getMaxResidual() { + return resMax; + } + + + + /** Get the mean residual; + * @return mean residual + */ + public double getMeanResidual() { + return resMean; + } + + + + public void computeMetrics() throws RuggedException { + + //final RealVector longDiffVector; + //final RealVector latDiffVector; + //final RealVector altDiffVector; + RealVector distanceVector = new ArrayRealVector(); + double count=0; + resMax = 0; + int k = groundTruthMappings.size(); + + Iterator<Map.Entry<SensorPixel, GeodeticPoint>> gtIt = groundTruthMappings.iterator(); + + + while (gtIt.hasNext()) { + Map.Entry<SensorPixel, GeodeticPoint> gtMapping =gtIt.next(); + + + final SensorPixel gtSP = gtMapping.getKey(); + final GeodeticPoint gtGP = gtMapping.getValue(); + + AbsoluteDate date = sensor.getDate(gtSP.getLineNumber()); + + GeodeticPoint esGP = rugged.directLocation(date, sensor.getPosition(), + sensor.getLOS(date, (int) gtSP.getPixelNumber())); + + + double lonDiff = esGP.getLongitude() - gtGP.getLongitude(); + double latDiff = esGP.getLatitude() - gtGP.getLatitude(); + double altDiff = esGP.getAltitude() - gtGP.getAltitude(); + //longDiffVector.append(lonDiff); + //latDiffVector.append(latDiff); + //altDiffVector.append(altDiff); + double distance = Math.sqrt( lonDiff * lonDiff + latDiff * latDiff + altDiff * altDiff ); + count += distance; + if (distance > resMax) + { + resMax = distance; + } + //distanceVector.append(distance); + + } + + //resMax = distanceVector.getMaxValue(); + //System.out.format(Locale.US, "max: %3.6e %n ",distanceVector.getMaxValue() ); + + resMean = count / k ; + //System.out.format("number of points %d %n", k); + } + + + + +} +