From 5e2e5427be01a74d7943bcb6af0176f0776e07f5 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Wed, 24 Dec 2014 16:12:19 +0100 Subject: [PATCH] Added partial derivatives for line-of-sights. The derivatives are computed with respect to transforms parameters. This is the first step towards los calibration. --- .../orekit/rugged/errors/RuggedMessages.java | 3 +- .../org/orekit/rugged/los/FixedRotation.java | 82 +++++++- .../org/orekit/rugged/los/LOSBuilder.java | 176 +++++++++++++----- .../org/orekit/rugged/los/LOSTransform.java | 19 +- .../orekit/rugged/los/PolynomialRotation.java | 111 ++++++++++- .../orekit/rugged/los/TimeDependentLOS.java | 13 +- .../los/TimeIndependentLOSTransform.java | 26 ++- .../orekit/rugged/utils/ParameterType.java | 32 ++++ .../orekit/rugged/utils/ParametricModel.java | 56 ++++++ .../org/orekit/rugged/RuggedMessages_de.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_en.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_es.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_fr.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_gl.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_it.utf8 | 3 + .../org/orekit/rugged/RuggedMessages_ro.utf8 | 3 + src/site/xdoc/changes.xml | 4 + .../rugged/errors/RuggedMessagesTest.java | 2 +- 18 files changed, 479 insertions(+), 66 deletions(-) create mode 100644 src/main/java/org/orekit/rugged/utils/ParameterType.java create mode 100644 src/main/java/org/orekit/rugged/utils/ParametricModel.java diff --git a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java index 031d104b..94e97731 100644 --- a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java +++ b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java @@ -64,7 +64,8 @@ public enum RuggedMessages implements Localizable { LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE("line-of-sight never crosses altitude {0}"), DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT("line-of-sight enters the Digital Elevation Model behind spacecraft!"), FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP("frame {0} does not match frame {1} from interpolator dump"), - NOT_INTERPOLATOR_DUMP_DATA("data is not an interpolator dump"); + NOT_INTERPOLATOR_DUMP_DATA("data is not an interpolator dump"), + ESTIMATED_PARAMETERS_NUMBER_MISMATCH("number of estimated parameters mismatch, expected {0} got {1}"); // CHECKSTYLE: resume JavadocVariable check diff --git a/src/main/java/org/orekit/rugged/los/FixedRotation.java b/src/main/java/org/orekit/rugged/los/FixedRotation.java index 0e73277e..bfd41e9b 100644 --- a/src/main/java/org/orekit/rugged/los/FixedRotation.java +++ b/src/main/java/org/orekit/rugged/los/FixedRotation.java @@ -16,8 +16,14 @@ */ package org.orekit.rugged.los; +import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; +import org.apache.commons.math3.geometry.euclidean.threed.FieldRotation; +import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D; import org.apache.commons.math3.geometry.euclidean.threed.Rotation; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.rugged.errors.RuggedException; +import org.orekit.rugged.errors.RuggedMessages; +import org.orekit.rugged.utils.ParameterType; /** {@link TimeIndependentLOSTransform LOS transform} based on a fixed rotation. * @author Luc Maisonobe @@ -25,14 +31,76 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; */ public class FixedRotation implements TimeIndependentLOSTransform { + /** Parameters type. */ + private final ParameterType type; + /** Underlying rotation. */ - private final Rotation rotation; + private Rotation rotation; + + /** Underlying rotation with derivatives. */ + private FieldRotation<DerivativeStructure> rDS; /** Simple constructor. - * @param rotation rotation to apply + * <p> + * The single parameter is the rotation angle. + * </p> + * @param type parameter type + * @param axis rotation axis + * @param angle rotation angle */ - public FixedRotation(final Rotation rotation) { - this.rotation = rotation; + public FixedRotation(final ParameterType type, final Vector3D axis, final double angle) { + this.type = type; + this.rotation = new Rotation(axis, angle); + this.rDS = null; + } + + /** {@inheritDoc} */ + @Override + public int getNbEstimatedParameters() { + return type == ParameterType.FIXED ? 0 : 1; + } + + /** {@inheritDoc} + * <p> + * The single parameter is the rotation angle. + * </p> + */ + @Override + public void getEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + checkSlice(length); + parameters[start] = rotation.getAngle(); + } + + /** {@inheritDoc} + * <p> + * The single parameter is the rotation angle. + * </p> + */ + @Override + public void setEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + checkSlice(length); + final Vector3D axis = rotation.getAxis(); + rotation = new Rotation(axis, parameters[start]); + final FieldVector3D<DerivativeStructure> axisDS = + new FieldVector3D<DerivativeStructure>(new DerivativeStructure(parameters.length, 1, axis.getX()), + new DerivativeStructure(parameters.length, 1, axis.getY()), + new DerivativeStructure(parameters.length, 1, axis.getZ())); + final DerivativeStructure angleDS = new DerivativeStructure(parameters.length, 1, start, parameters[start]); + rDS = new FieldRotation<DerivativeStructure>(axisDS, angleDS); + } + + /** Check the number of parameters of an array slice. + * @param length number of elements in the array slice to consider + * @exception RuggedException if the size of the slice does not match + * the {@link #getNbEstimatedParameters() number of estimated parameters} + */ + private void checkSlice(final int length) throws RuggedException { + if (getNbEstimatedParameters() != length) { + throw new RuggedException(RuggedMessages.ESTIMATED_PARAMETERS_NUMBER_MISMATCH, + getNbEstimatedParameters(), length); + } } /** {@inheritDoc} */ @@ -41,4 +109,10 @@ public class FixedRotation implements TimeIndependentLOSTransform { return rotation.applyTo(los); } + /** {@inheritDoc} */ + @Override + public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los) { + return rDS.applyTo(los); + } + } diff --git a/src/main/java/org/orekit/rugged/los/LOSBuilder.java b/src/main/java/org/orekit/rugged/los/LOSBuilder.java index fd034b44..b25fadf1 100644 --- a/src/main/java/org/orekit/rugged/los/LOSBuilder.java +++ b/src/main/java/org/orekit/rugged/los/LOSBuilder.java @@ -17,12 +17,15 @@ package org.orekit.rugged.los; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; -import org.orekit.rugged.api.Rugged; +import org.orekit.rugged.errors.RuggedException; +import org.orekit.rugged.errors.RuggedMessages; +import org.orekit.rugged.utils.ParametricModel; import org.orekit.time.AbsoluteDate; /** Builder for lines-of-sight list. @@ -110,69 +113,43 @@ public class LOSBuilder { this.transform = transform; } - /** Get the underlying transform. - * @return underlying time-independent transform - */ - public TimeIndependentLOSTransform getTransform() { - return transform; - } - /** {@inheritDoc} */ @Override - public Vector3D transformLOS(final int i, final Vector3D los, final AbsoluteDate date) { - return transform.transformLOS(i, los); + public int getNbEstimatedParameters() { + return transform.getNbEstimatedParameters(); } - } - - /** Implement time-independent LOS by applying all registered transforms at construction. */ - private static class FixedLOS implements TimeDependentLOS { - - /** Fixed direction for los. */ - private final Vector3D[] los; - - /** Simple constructor. - * @param raw raw directions - * @param transforms transforms to apply (must be time-independent!) - */ - public FixedLOS(final List<Vector3D> raw, final List<LOSTransform> transforms) { - - los = new Vector3D[raw.size()]; - - // apply transforms only once - for (int i = 0; i < raw.size(); ++i) { - Vector3D v = raw.get(i); - for (final LOSTransform transform : transforms) { - v = ((TransformAdapter) transform).getTransform().transformLOS(i, v); - } - los[i] = v.normalize(); - } - + /** {@inheritDoc} */ + @Override + public void getEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + transform.getEstimatedParameters(parameters, start, length); } /** {@inheritDoc} */ - public int getNbPixels() { - return los.length; + @Override + public void setEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + transform.setEstimatedParameters(parameters, start, length); } /** {@inheritDoc} */ - public Vector3D getLOS(final int index, final AbsoluteDate date) { - return los[index]; + @Override + public Vector3D transformLOS(final int i, final Vector3D los, final AbsoluteDate date) { + return transform.transformLOS(i, los); } /** {@inheritDoc} */ - public FieldVector3D<DerivativeStructure> getLOS(final int index, final AbsoluteDate date, - final double[] parameters) { - // fixed LOS do not depend on any parameters - return new FieldVector3D<DerivativeStructure>(new DerivativeStructure(parameters.length, 1, los[index].getX()), - new DerivativeStructure(parameters.length, 1, los[index].getY()), - new DerivativeStructure(parameters.length, 1, los[index].getZ())); + @Override + public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los, + final AbsoluteDate date) { + return transform.transformLOS(i, los); } } - /** Implement time-dependent LOS by applying all registered transforms at runtime. */ - private static class TransformsSequenceLOS implements TimeDependentLOS { + /** Implement time-independent LOS by recomputing directions by applying all transforms each time. */ + private static class TransformsSequenceLOS implements ParametricModel, TimeDependentLOS { /** Raw direction. */ private final Vector3D[] raw; @@ -180,6 +157,9 @@ public class LOSBuilder { /** Transforms to be applied. */ private final LOSTransform[] transforms; + /** Total number of estimated parameters. */ + private final int total; + /** Simple constructor. * @param raw raw directions * @param transforms transforms to apply @@ -189,19 +169,76 @@ public class LOSBuilder { // copy the lists, to ensure immutability of the built object, // in case addTransform is called again after build // or the raw LOS list is changed by caller - this.raw = new Vector3D[raw.size()]; for (int i = 0; i < raw.size(); ++i) { this.raw[i] = raw.get(i); } this.transforms = new LOSTransform[transforms.size()]; + int n = 0; for (int i = 0; i < transforms.size(); ++i) { - this.transforms[i] = transforms.get(i); + final LOSTransform transform = transforms.get(i); + this.transforms[i] = transform; + n += transform.getNbEstimatedParameters(); + } + this.total = n; + + } + + /** {@inheritDoc} */ + @Override + public int getNbEstimatedParameters() { + return total; + } + + /** {@inheritDoc} */ + @Override + public void getEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + + // global check + checkSlice(length); + + // retrieve parameters for all transforms + int offset = 0; + for (final ParametricModel model : transforms) { + final int n = model.getNbEstimatedParameters(); + model.getEstimatedParameters(parameters, offset, n); + offset += n; + } + + } + + /** {@inheritDoc} */ + @Override + public void setEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + + // global check + checkSlice(length); + + // set parameters for all transforms + int offset = 0; + for (final ParametricModel model : transforms) { + final int n = model.getNbEstimatedParameters(); + model.setEstimatedParameters(parameters, offset, n); + offset += n; } } + /** Check the number of parameters of an array slice. + * @param length number of elements in the array slice to consider + * @exception RuggedException if the size of the slice does not match + * the {@link #getNbEstimatedParameters() number of estimated parameters} + */ + private void checkSlice(final int length) throws RuggedException { + if (getNbEstimatedParameters() != length) { + throw new RuggedException(RuggedMessages.ESTIMATED_PARAMETERS_NUMBER_MISMATCH, + getNbEstimatedParameters(), length); + } + } + /** {@inheritDoc} */ public int getNbPixels() { return raw.length; @@ -218,6 +255,7 @@ public class LOSBuilder { } /** {@inheritDoc} */ + @Override public FieldVector3D<DerivativeStructure> getLOS(final int index, final AbsoluteDate date, final double[] parameters) { // non-adjustable LOS do not depend on any parameters @@ -229,4 +267,44 @@ public class LOSBuilder { } + /** Implement time-independent LOS by computing directions only when parameters are changed. */ + private static class FixedLOS extends TransformsSequenceLOS { + + /** transformed direction for los. */ + private final Vector3D[] transformed; + + /** Simple constructor. + * @param raw raw directions + * @param transforms transforms to apply (must be time-independent!) + */ + public FixedLOS(final List<Vector3D> raw, final List<LOSTransform> transforms) { + super(raw, transforms); + transformed = new Vector3D[raw.size()]; + } + + /** {@inheritDoc} */ + @Override + public void setEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + + // update the transforms + super.setEstimatedParameters(parameters, start, length); + + // unset the directions, to ensure they get recomputed if needed + Arrays.fill(transformed, null); + + } + + /** {@inheritDoc} */ + @Override + public Vector3D getLOS(final int index, final AbsoluteDate date) { + if (transformed[index] == null) { + // recompute the transformed los direction only if needed + transformed[index] = super.getLOS(index, date); + } + return transformed[index]; + } + + } + } diff --git a/src/main/java/org/orekit/rugged/los/LOSTransform.java b/src/main/java/org/orekit/rugged/los/LOSTransform.java index ff085f72..840d1a6c 100644 --- a/src/main/java/org/orekit/rugged/los/LOSTransform.java +++ b/src/main/java/org/orekit/rugged/los/LOSTransform.java @@ -16,14 +16,17 @@ */ package org.orekit.rugged.los; +import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; +import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.rugged.utils.ParametricModel; import org.orekit.time.AbsoluteDate; /** Interface for lines-of-sight tranforms. * @author Luc Maisonobe * @see LOSBuilder */ -interface LOSTransform { +interface LOSTransform extends ParametricModel { /** Transform a line-of-sight. * @param i los pixel index @@ -33,4 +36,18 @@ interface LOSTransform { */ Vector3D transformLOS(int i, Vector3D los, AbsoluteDate date); + /** Transform a line-of-sight and its partial derivatives. + * <p> + * This method is used for LOS calibration purposes. It allows to compute + * the Jacobian matrix of the LOS with respect to the parameters, which + * are typically polynomials coefficients representing rotation angles. + * These polynomials can be used for example to model thermo-elastic effects. + * </p> + * @param index los pixel index + * @param date date + * @param los line-of-sight to transform + * @return line of sight, and its first partial derivatives with respect to the parameters + */ + FieldVector3D<DerivativeStructure> transformLOS(int index, FieldVector3D<DerivativeStructure> los, AbsoluteDate date); + } diff --git a/src/main/java/org/orekit/rugged/los/PolynomialRotation.java b/src/main/java/org/orekit/rugged/los/PolynomialRotation.java index cc97a47f..8502dd92 100644 --- a/src/main/java/org/orekit/rugged/los/PolynomialRotation.java +++ b/src/main/java/org/orekit/rugged/los/PolynomialRotation.java @@ -16,9 +16,15 @@ */ package org.orekit.rugged.los; +import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; import org.apache.commons.math3.analysis.polynomials.PolynomialFunction; +import org.apache.commons.math3.geometry.euclidean.threed.FieldRotation; +import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D; import org.apache.commons.math3.geometry.euclidean.threed.Rotation; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.rugged.errors.RuggedException; +import org.orekit.rugged.errors.RuggedMessages; +import org.orekit.rugged.utils.ParameterType; import org.orekit.time.AbsoluteDate; /** {@link LOSTransform LOS transform} based on a rotation with polynomial angle. @@ -27,33 +33,124 @@ import org.orekit.time.AbsoluteDate; */ public class PolynomialRotation implements LOSTransform { + /** Parameters type. */ + private final ParameterType type; + /** Rotation axis. */ private final Vector3D axis; /** Rotation angle polynomial. */ - private final PolynomialFunction angle; + private PolynomialFunction angle; + + /** Rotation axis and derivatives. */ + private FieldVector3D<DerivativeStructure> axisDS; + + /** Rotation angle polynomial and derivatives. */ + private DerivativeStructure[] angleDS; /** Reference date for polynomial evaluation. */ private final AbsoluteDate referenceDate; /** Simple constructor. + * <p> + * The angle of the rotation is evaluated as a polynomial in t, + * where t is the duration in seconds between evaluation date and + * reference date. The parameters are the polynomial coefficients, + * with the constant term at index 0. + * </p> + * @param type parameters type * @param axis rotation axis - * @param angle rotation angle as a polynomial in t, where t - * is the duration in seconds between evaluation date and reference date * @param referenceDate reference date for the polynomial angle + * @param angleCoeffs polynomial coefficients of the polynomial angle, + * with the constant term at index 0 */ - public PolynomialRotation(final Vector3D axis, - final PolynomialFunction angle, - final AbsoluteDate referenceDate) { + public PolynomialRotation(final ParameterType type, + final Vector3D axis, + final AbsoluteDate referenceDate, + final double ... angleCoeffs) { + this.type = type; this.axis = axis; - this.angle = angle; + this.angle = new PolynomialFunction(angleCoeffs); this.referenceDate = referenceDate; } + /** {@inheritDoc} */ + @Override + public int getNbEstimatedParameters() { + return type == ParameterType.FIXED ? 0 : (angle.degree() + 1); + } + + /** {@inheritDoc} + * <p> + * The parameters are the polynomial coefficients, + * with the constant term at index 0. + * </p> + */ + @Override + public void getEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + checkSlice(length); + System.arraycopy(angle.getCoefficients(), 0, length, start, length); + } + + /** {@inheritDoc} + * <p> + * The parameters are the polynomial coefficients, + * with the constant term at index 0. + * </p> + */ + @Override + public void setEstimatedParameters(final double[] parameters, final int start, final int length) + throws RuggedException { + + checkSlice(length); + + // regular rotation + angle = new PolynomialFunction(parameters); + + // prepare components to compute rotation with derivatives + axisDS = new FieldVector3D<DerivativeStructure>(new DerivativeStructure(parameters.length, 1, axis.getX()), + new DerivativeStructure(parameters.length, 1, axis.getY()), + new DerivativeStructure(parameters.length, 1, axis.getZ())); + angleDS = new DerivativeStructure[length]; + for (int i = 0; i < length; ++i) { + angleDS[i] = new DerivativeStructure(parameters.length, 1, start + i, parameters[start + i]); + } + + } + + /** Check the number of parameters of an array slice. + * @param length number of elements in the array slice to consider + * @exception RuggedException if the size of the slice does not match + * the {@link #getNbEstimatedParameters() number of estimated parameters} + */ + private void checkSlice(final int length) throws RuggedException { + if (getNbEstimatedParameters() != length) { + throw new RuggedException(RuggedMessages.ESTIMATED_PARAMETERS_NUMBER_MISMATCH, + getNbEstimatedParameters(), length); + } + } + /** {@inheritDoc} */ @Override public Vector3D transformLOS(final int i, final Vector3D los, final AbsoluteDate date) { return new Rotation(axis, angle.value(date.durationFrom(referenceDate))).applyTo(los); } + /** {@inheritDoc} */ + @Override + public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los, + final AbsoluteDate date) { + + // evaluate polynomial, with all its partial derivatives + final double t = date.durationFrom(referenceDate); + DerivativeStructure alpha = axisDS.getX().getField().getZero(); + for (int k = angleDS.length - 1; k >= 0; --k) { + alpha = alpha.multiply(t).add(angleDS[k]); + } + + return new FieldRotation<DerivativeStructure>(axisDS, alpha).applyTo(los); + + } + } diff --git a/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java b/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java index 0479a9b1..8b7891ed 100644 --- a/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java +++ b/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java @@ -19,13 +19,14 @@ package org.orekit.rugged.los; import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.rugged.utils.ParametricModel; import org.orekit.time.AbsoluteDate; /** Interface representing a line-of-sight which depends on time. * @see LineSensor * @author Luc Maisonobe */ -public interface TimeDependentLOS { +public interface TimeDependentLOS extends ParametricModel { /** Get the number of pixels. * @return number of pixels @@ -44,7 +45,15 @@ public interface TimeDependentLOS { * This method is used for LOS calibration purposes. It allows to compute * the Jacobian matrix of the LOS with respect to the parameters, which * are typically polynomials coefficients representing rotation angles. - * These polynomials can be used for example to model thermo-elestic effects. + * These polynomials can be used for example to model thermo-elastic effects. + * </p> + * <p> + * Note that in order for the partial derivatives to be properly set up, the + * {@link #setEstimatedParameters(double[], int, int) setEstimatedParameters} + * <em>must</em> have been called at least once before this method and its + * {@code start} parameter will be used to ensure the partial derivatives are + * ordered in the same way in the returned vector as they were in the set + * parameters. * </p> * @param index los pixel index * @param date date diff --git a/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java b/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java index c75de032..bee09499 100644 --- a/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java +++ b/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java @@ -16,13 +16,16 @@ */ package org.orekit.rugged.los; +import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; +import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.orekit.rugged.utils.ParametricModel; /** Interface for lines-of-sight tranforms that do not depend on time. * @author Luc Maisonobe * @see LOSBuilder */ -interface TimeIndependentLOSTransform { +interface TimeIndependentLOSTransform extends ParametricModel { /** Transform a line-of-sight. * @param i los pixel index @@ -31,4 +34,25 @@ interface TimeIndependentLOSTransform { */ Vector3D transformLOS(int i, Vector3D los); + /** Transform a line-of-sight and its partial derivatives. + * <p> + * This method is used for LOS calibration purposes. It allows to compute + * the Jacobian matrix of the LOS with respect to the parameters, which + * are typically polynomials coefficients representing rotation angles. + * These polynomials can be used for example to model thermo-elastic effects. + * </p> + * <p> + * Note that in order for the partial derivatives to be properly set up, the + * {@link #setEstimatedParameters(double[], int, int) setEstimatedParameters} + * <em>must</em> have been called at least once before this method and its + * {@code start} parameter will be used to ensure the partial derivatives are + * ordered in the same way in the returned vector as they were in the set + * parameters. + * </p> + * @param index los pixel index + * @param los line-of-sight to transform + * @return line of sight, and its first partial derivatives with respect to the parameters + */ + FieldVector3D<DerivativeStructure> transformLOS(int index, FieldVector3D<DerivativeStructure> los); + } diff --git a/src/main/java/org/orekit/rugged/utils/ParameterType.java b/src/main/java/org/orekit/rugged/utils/ParameterType.java new file mode 100644 index 00000000..d7bfba16 --- /dev/null +++ b/src/main/java/org/orekit/rugged/utils/ParameterType.java @@ -0,0 +1,32 @@ +/* Copyright 2013-2014 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 org.orekit.rugged.utils; + + +/** Type of parameter. + * @author Luc Maisonobe + * @see ParametricModel + */ +public enum ParameterType { + + /** Type of parameter which cannot be changed at all. */ + FIXED, + + /** Type of parameter which can be estimated, i.e. its value can change. */ + ESTIMATED; + +} diff --git a/src/main/java/org/orekit/rugged/utils/ParametricModel.java b/src/main/java/org/orekit/rugged/utils/ParametricModel.java new file mode 100644 index 00000000..0e3be2a7 --- /dev/null +++ b/src/main/java/org/orekit/rugged/utils/ParametricModel.java @@ -0,0 +1,56 @@ +/* Copyright 2013-2014 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 org.orekit.rugged.utils; + +import org.orekit.rugged.errors.RuggedException; + + +/** Interface for models that have parameters. + * <p> + * The parameters are typically polynomial coefficients, for example + * to model thermo-elastic deformations of the sensor or spacecraft. + * </p> + * @author Luc Maisonobe + */ +public interface ParametricModel { + + /** Get the number of estimated parameters. + * @return number of estimated parameters + */ + int getNbEstimatedParameters(); + + /** Get the current values of the estimated parameters. + * @param parameters global array where to put the parameters + * @param start start index of the array slice to consider + * @param length number of elements in the array slice to consider + * @exception RuggedException if the size of the slice does not match + * the {@link #getNbEstimatedParameters() number of estimated parameters} + */ + void getEstimatedParameters(double[] parameters, int start, int length) + throws RuggedException; + + /** Set new values for the estimated parameters. + * @param parameters global array containing the parameters to set (among others) + * @param start start index of the array slice to consider + * @param length number of elements in the array slice to consider + * @exception RuggedException if the size of the slice does not match + * the {@link #getNbEstimatedParameters() number of estimated parameters} + */ + void setEstimatedParameters(double[] parameters, int start, int length) + throws RuggedException; + +} diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 index 62efdb1d..999dbcf4 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = der Rahmen {0} passt nicht zum Rahmen { # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = die Angabe ist nicht das Backup der Interpolation + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 index 1c6fb33b..bcf1729e 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = frame {0} does not match frame {1} from # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = data is not an interpolator dump + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = number of estimated parameters mismatch, expected {0} got {1} diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 index 3fe2e545..3c1ff3eb 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = el sistema de referencia {0} no corresp # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = los datos no están en el volcado de datos del interpolador + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 index 96e63b5a..d8842ce1 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = le repère {0} ne correspond pas au rep # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = les données ne correspondent pas à une sauvegarde d''interpolateur + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = incohérence du nombre de paramètres estimés, {0} attendus, {1} renseignés diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 index f09aa9a8..a841bad3 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = o sistema de referencia {0} non corresp # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = os datos non están no baleirado de datos do interpolador + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 index d894f090..69a983c8 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = il riferimento {0} non corrisponde al r # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = i dati non corrispondono a un salvatagggio d''interpolatore + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = <MISSING TRANSLATION> diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 index 5dc5eae4..33d24adc 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 @@ -42,3 +42,6 @@ FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP = sistemul de coordonate {0} nu se potriv # data is not an interpolator dump NOT_INTERPOLATOR_DUMP_DATA = datele nu reprezintă o copie de siguranță a interpolatorului + +# number of estimated parameters mismatch, expected {0} got {1} +ESTIMATED_PARAMETERS_NUMBER_MISMATCH = <MISSING TRANSLATION> diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index 6c35af4d..8402869d 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -22,6 +22,10 @@ <body> <release version="1.0" date="TBD" description="TBD"> + <action dev="luc" type="add" > + Added partial derivatives for line-of-sights with respect to transforms parameters. + This is the first step towards los calibration. + </action> <action dev="luc" type="add" > Added sequences of transforms for lines-of-sight. </action> diff --git a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java index 41f8cc7f..eb225981 100644 --- a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java +++ b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java @@ -30,7 +30,7 @@ public class RuggedMessagesTest { @Test public void testMessageNumber() { - Assert.assertEquals(15, RuggedMessages.values().length); + Assert.assertEquals(16, RuggedMessages.values().length); } @Test -- GitLab