All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.orekit.rugged.los.LOSBuilder Maven / Gradle / Ivy

Go to download

Rugged is an Orekit add-on handling Digital Elevation Models contribution to line of sight computation

There is a newer version: 3.0
Show newest version
/* 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