diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index 7a90dbf6123389584f3a2f69b4b5c527acff9cad..a6e24cdfe259aeded0439491a414623166fe6687 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -29,6 +30,7 @@ import org.hipparchus.linear.Array2DRowRealMatrix; import org.hipparchus.linear.ArrayRealVector; import org.hipparchus.linear.RealMatrix; import org.hipparchus.linear.RealVector; +import org.hipparchus.linear.DiagonalMatrix; import org.hipparchus.optim.ConvergenceChecker; import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresBuilder; import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresOptimizer; @@ -727,7 +729,7 @@ public class Rugged { * @return distance computing * @exception RuggedException if sensor is unknown */ - public double + public double[] distanceBetweenLOS(final LineSensor sensorA, final AbsoluteDate dateA, final double pixelA, final SpacecraftToObservedBody scToBodyA, @@ -760,9 +762,9 @@ public class Rugged { final Vector3D vALocal = sensorA.getLOS(dateA, pixelA); // V_a : line of // sight's // vectorA - final Vector3D vBLocal = sensorB.getLOS(dateB, pixelB); // V_a : line of + final Vector3D vBLocal = sensorB.getLOS(dateB, pixelB); // V_b : line of // sight's - // vectorA + // vectorb // positions final Vector3D sALocal = sensorA.getPosition(); // S_a : sensorA 's @@ -775,6 +777,26 @@ public class Rugged { final Vector3D sB = trasnformScToBodyB.transformPosition(sBLocal); final Vector3D vB = trasnformScToBodyB.transformVector(vBLocal); + final GeodeticPoint gpB = algorithm + .refineIntersection(ellipsoid,sB, vB, algorithm + .intersection(ellipsoid, sB, vB)); + + + GeodeticPoint gpB2 = directLocation(dateB, sensorB.getPosition(), + sensorB.getLOS(dateB, pixelB)); + /*double GEOdistance = DistanceTools.computeDistanceRad(gpB.getLongitude(), gpB.getLatitude(), + gpB2.getLongitude(), gpB2.getLatitude()); + + System.out.format("GEO dist %1.6e %n",GEOdistance); + System.out.format(Locale.US, "%n geodetic position B: φ = %8.10f °, λ = %8.10f °, h = %8.3f m%n", + FastMath.toDegrees(gpB.getLatitude()), + FastMath.toDegrees(gpB.getLongitude()),gpB.getAltitude()); + + System.out.format(Locale.US, "geodetic position B2 : φ = %8.10f °, λ = %8.10f °, h = %8.3f m%n%n", + FastMath.toDegrees(gpB2.getLatitude()), + FastMath.toDegrees(gpB2.getLongitude()),gpB2.getAltitude()); */ + + final Vector3D vBase = sB.subtract(sA); // S_b - S_a final double svA = Vector3D.dotProduct(vBase, vA); // SV_a = (S_b - // S_a).V_a @@ -784,11 +806,12 @@ public class Rugged { final double vAvB = Vector3D.dotProduct(vA, vB); // V_a.V_b // Test using |SaSb,Va,Vb |/||Va^Vb|| - // final Vector3D w = Vector3D.crossProduct(vA, vB); - // final Vector3D vect = Vector3D.crossProduct(vBase,vA); - // final double k = Vector3D.dotProduct(vect, vB); - // final double dist = Math.abs(k) /w.getNorm(); - + //final Vector3D w = Vector3D.crossProduct(vA, vB); + //final Vector3D vect = Vector3D.crossProduct(vBase,vA); + //final double k = Vector3D.dotProduct(vect, vB); + //final double dist = Math.abs(k) /w.getNorm(); + //System.out.format("dist %f %n",dist); + // Compute lambda_b = (SV_a * V_a.V_b - SV_b) / (1 - (V_a.V_b)²) final double lambdaB = (svA * vAvB - svB) / (1 - vAvB * vAvB); @@ -803,6 +826,12 @@ public class Rugged { // V_b final Vector3D vDistance = mB.subtract(mA); // M_b - M_a + + final Vector3D midPoint = (mB.add(mA)).scalarMultiply(0.5); + //System.out.format("mid Point x %f y %f z %f %n",midPoint.getX(),midPoint.getY(),midPoint.getZ()); + //System.out.format("mid Point Norm %f %n",midPoint.getNorm()); + + // System.out.format("vDistance %f %f %f // ",vDistance.getX(),vDistance.getY(),vDistance.getZ()); @@ -812,7 +841,7 @@ public class Rugged { // final double equB = Vector3D.dotProduct(mAmB, vB); // Get the euclidean norm - final double d = vDistance.getNorm(); + final double[] d = {vDistance.getNorm(),midPoint.getNorm()}; return d; } @@ -946,10 +975,26 @@ public class Rugged { // M_a // Get the euclidean norm + + final FieldVector3D<DerivativeStructure> midPoint = (mB.add(mA)).scalarMultiply(0.5); + //System.out.format("mid Point x %f y %f z %f %n",midPoint.getX(),midPoint.getY(),midPoint.getZ()); + //System.out.format("mid Point Norm %f %n",midPoint.getNorm()); + + + // System.out.format("vDistance %f %f %f + // ",vDistance.getX(),vDistance.getY(),vDistance.getZ()); + + // equA and equB should be 0 + // final Vector3D mAmB= mB.subtract(mA); + // final double equA = Vector3D.dotProduct(mAmB, vA); + // final double equB = Vector3D.dotProduct(mAmB, vB); + + // Get the euclidean norm + final DerivativeStructure dEarth = midPoint.getNorm(); final DerivativeStructure d = vDistance.getNorm(); - return new DerivativeStructure[] { - d - }; + + + return new DerivativeStructure[] {d, dEarth}; } /** @@ -963,6 +1008,9 @@ public class Rugged { * @param parametersConvergenceThreshold convergence threshold on normalized * parameters (dimensionless, related to parameters scales) * @param ruggedA rugged instance from viewing model A + * @param earthConstraintWeight weight for earthconstraintWeight (between 0 and 1). Weighting is applied as follow : + * (1-earthConstraintWeight) for losDistance weighting + * earthConstraintWeight for earthDistance weighting * @return optimum of the least squares problem * @exception RuggedException if several parameters with the same name * exist, if no parameters have been selected for estimation, or @@ -973,7 +1021,7 @@ public class Rugged { final Collection<SensorToSensorMapping> references, final int maxEvaluations, final double parametersConvergenceThreshold, - Rugged ruggedA) + Rugged ruggedA,final double earthConstraintWeight) throws RuggedException { try { @@ -1013,13 +1061,23 @@ public class Rugged { if (n == 0) { throw new RuggedException(RuggedMessages.NO_REFERENCE_MAPPINGS); } + + n = 2*n; + + final double[] target = new double[n]; + final double[] weight = new double[n]; int k = 0; for (final SensorToSensorMapping reference : references) { - for (final Double distMeas : reference.getMapDistance()) { - target[k++] = distMeas.doubleValue(); // distances - // measurements - } + for (final Map.Entry<SensorPixel, SensorPixel> mapping : reference.getMappings()) { + final SensorPixel spA = mapping.getKey(); + Double [] distMeas = reference.getDistance(spA); + weight[k] = 1.0 - earthConstraintWeight; + target[k++] = distMeas[0].doubleValue(); // LOS distance + weight[k] = earthConstraintWeight; + target[k++] = distMeas[1].doubleValue(); // Earth distance + } + } // prevent parameters to exceed their prescribed bounds @@ -1053,7 +1111,6 @@ public class Rugged { int i = 0; for (final ParameterDriver driver : selected.getDrivers()) { driver.setNormalizedValue(point.getEntry(i++)); - // TODO: to be confirmed with the remark done above. } // compute distance and its partial derivatives @@ -1094,7 +1151,7 @@ public class Rugged { } else { // extract the value value.setEntry(l, ilResult[0].getValue()); - + value.setEntry(l + 1, ilResult[1].getValue()); // extract the Jacobian final int[] orders = new int[selected .getNbParams()]; @@ -1107,12 +1164,17 @@ public class Rugged { ilResult[0] .getPartialDerivative(orders) * scale); + + jacobian.setEntry(l + 1, m, + ilResult[1] + .getPartialDerivative(orders) * + scale); + orders[m] = 0; m++; } } - - l += 1; // pass to the next evaluation + l += 2; // pass to the next evaluation } } @@ -1130,12 +1192,12 @@ public class Rugged { // set up the least squares problem final LeastSquaresProblem problem = new LeastSquaresBuilder() .lazyEvaluation(false).maxIterations(maxEvaluations) - .maxEvaluations(maxEvaluations).weight(null).start(start) + .maxEvaluations(maxEvaluations).weight(new DiagonalMatrix(weight)).start(start) .target(target).parameterValidator(validator).checker(checker) .model(model).build(); // set up the optimizer - // final LeastSquaresOptimizer optimizer = new + //final LeastSquaresOptimizer optimizer = new // LevenbergMarquardtOptimizer(); final LeastSquaresOptimizer optimizer = new GaussNewtonOptimizer() .withDecomposition(GaussNewtonOptimizer.Decomposition.QR);