org.orekit.rugged.los.LOSBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rugged Show documentation
Show all versions of rugged Show documentation
Rugged is an Orekit add-on handling Digital Elevation Models
contribution to line of sight computation
/* 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 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.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.
*
* This class implements the builder pattern to create {@link TimeDependentLOS} instances.
* It does so by using a fluent API in order to clarify reading and allow
* later extensions with new configuration parameters.
*
*
* This builder aims at creating lines-of-sight directions which are
* the result of several transforms applied to an initial list of raw
* directions. It therefore allows to take into account the optical
* path due to mirrors and the alignments of sensors frames with respect
* to a spacecraft.
*
* @see TimeDependentLOS
* @see Builder pattern (wikipedia)
* @see Fluent interface (wikipedia)
* @author Luc Maisonobe
*/
public class LOSBuilder {
/** Raw fixed ine-of-sights. */
private final List rawLOS;
/** Transforms to be applied. */
private final List transforms;
/** Flag for time-independent only transforms. */
private boolean timeIndependent;
/** Create builder.
* @param rawLOS raw fixed lines-of-sight
*/
public LOSBuilder(final List rawLOS) {
this.rawLOS = rawLOS;
this.transforms = new ArrayList();
this.timeIndependent = true;
}
/** Add a transform to be applied after the already registered transforms.
* @param transform transform to be applied to the lines-of-sight
* @return the builder instance
*/
public LOSBuilder addTransform(final TimeIndependentLOSTransform transform) {
transforms.add(new TransformAdapter(transform));
return this;
}
/** Add a transform to be applied after the already registered transforms.
* @param transform transform to be applied to the lines-of-sight
* @return the builder instance
*/
public LOSBuilder addTransform(final LOSTransform transform) {
transforms.add(transform);
timeIndependent = false;
return this;
}
/** Build a lines-of-sight provider.
* @return lines-of-sight provider
*/
public TimeDependentLOS build() {
if (timeIndependent) {
// fast implementation for time-independent lines-of-sight
return new FixedLOS(rawLOS, transforms);
} else {
// regular implementation, for time-dependent lines-of-sight
return new TransformsSequenceLOS(rawLOS, transforms);
}
}
/** Adapter from time-independent transform to time-dependent transform. */
private static class TransformAdapter implements LOSTransform {
/** Underlying transform. */
private final TimeIndependentLOSTransform transform;
/** Simple constructor.
* @param transform underlying time-independent transform
*/
public TransformAdapter(final TimeIndependentLOSTransform transform) {
this.transform = transform;
}
/** {@inheritDoc} */
@Override
public int getNbEstimatedParameters() {
return transform.getNbEstimatedParameters();
}
/** {@inheritDoc} */
@Override
public void getEstimatedParameters(final double[] parameters, final int start, final int length)
throws RuggedException {
transform.getEstimatedParameters(parameters, start, length);
}
/** {@inheritDoc} */
@Override
public void setEstimatedParameters(final double[] parameters, final int start, final int length)
throws RuggedException {
transform.setEstimatedParameters(parameters, start, length);
}
/** {@inheritDoc} */
@Override
public Vector3D transformLOS(final int i, final Vector3D los, final AbsoluteDate date) {
return transform.transformLOS(i, los);
}
/** {@inheritDoc} */
@Override
public FieldVector3D transformLOS(final int i, final FieldVector3D los,
final AbsoluteDate date) {
return transform.transformLOS(i, los);
}
}
/** 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;
/** 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
*/
public TransformsSequenceLOS(final List raw, final List transforms) {
// 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) {
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;
}
/** {@inheritDoc} */
@Override
public Vector3D getLOS(final int index, final AbsoluteDate date) {
Vector3D los = raw[index];
for (final LOSTransform transform : transforms) {
los = transform.transformLOS(index, los, date);
}
return los.normalize();
}
/** {@inheritDoc} */
@Override
public FieldVector3D getLOS(final int index, final AbsoluteDate date,
final double[] parameters) {
// non-adjustable LOS do not depend on any parameters
final Vector3D los = getLOS(index, date);
return new FieldVector3D(new DerivativeStructure(parameters.length, 1, los.getX()),
new DerivativeStructure(parameters.length, 1, los.getY()),
new DerivativeStructure(parameters.length, 1, los.getZ()));
}
}
/** 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 raw, final List 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];
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy