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

org.orekit.frames.UpdatableFrame Maven / Gradle / Ivy

Go to download

OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library. It provides basic elements (orbits, dates, attitude, frames ...) and various algorithms to handle them (conversions, analytical and numerical propagation, pointing ...).

There is a newer version: 12.2
Show newest version
/* Copyright 2002-2019 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.frames;

import java.util.concurrent.atomic.AtomicReference;

import org.hipparchus.RealFieldElement;
import org.orekit.errors.FrameAncestorException;
import org.orekit.errors.OrekitMessages;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;


/** Frame whose transform from its parent can be updated.
 * 

This class allows to control the relative position of two parts * of the global frames tree using any two frames in each part as * control handles. Consider the following simplified frames tree as an * example:

*
 *              GCRF
 *                |
 *  --------------------------------
 *  |             |                |
 * Sun        satellite          Earth
 *                |                |
 *        on-board antenna   ground station
 *                                 |
 *                          tracking antenna
 * 
*

Tracking measurements really correspond to the link between the ground * and on-board antennas. This is tightly linked to the transform between * these two frames, however neither frame is the direct parent frame of the * other one: the path involves four intermediate frames. When we process a * measurement, what we really want to update is the transform that defines * the satellite frame with respect to its parent GCRF frame.

*

In order to implement the above case, the satellite frame is defined * as an instance of this class and its {@link #updateTransform(Frame, Frame, * Transform, AbsoluteDate) updateTransform} would be called each time we want * to adjust the frame, i.e. each time we get a new measurement between the * two antennas.

* @author Luc Maisonobe */ public class UpdatableFrame extends Frame { /** Serializable UID. */ private static final long serialVersionUID = -2075893064211339303L; /** Build a non-inertial frame from its transform with respect to its parent. *

calling this constructor is equivalent to call * {@link #UpdatableFrame(Frame, Transform, String, boolean) * UpdatableFrame(parent, transform, name, false)}.

* @param parent parent frame (must be non-null) * @param transform transform from parent frame to instance * @param name name of the frame * @exception IllegalArgumentException if the parent frame is null */ public UpdatableFrame(final Frame parent, final Transform transform, final String name) throws IllegalArgumentException { this(parent, transform, name, false); } /** Build a frame from its transform with respect to its parent. *

The convention for the transform is that it is from parent * frame to instance. This means that the two following frames * are similar:

*
     * Frame frame1 = new Frame(FramesFactory.getGCRF(), new Transform(t1, t2));
     * Frame frame2 = new Frame(new Frame(FramesFactory.getGCRF(), t1), t2);
     * 
* @param parent parent frame (must be non-null) * @param transform transform from parent frame to instance * @param name name of the frame * @param pseudoInertial true if frame is considered pseudo-inertial * (i.e. suitable for propagating orbit) * @exception IllegalArgumentException if the parent frame is null */ public UpdatableFrame(final Frame parent, final Transform transform, final String name, final boolean pseudoInertial) throws IllegalArgumentException { super(parent, new UpdatableProvider(transform), name, pseudoInertial); } /** Update the transform from parent frame implicitly according to two other * frames. *

This method allows to control the relative position of two parts * of the global frames tree using any two frames in each part as * control handles. Consider the following simplified frames tree as an * example:

*
     *              GCRF
     *                |
     *  --------------------------------
     *  |             |                |
     * Sun        satellite          Earth
     *                |                |
     *        on-board antenna   ground station
     *                                 |
     *                          tracking antenna
     * 
*

Tracking measurements really correspond to the link between the ground * and on-board antennas. This is tightly linked to the transform between * these two frames, however neither frame is the direct parent frame of the * other one: the path involves four intermediate frames. When we process a * measurement, what we really want to update is the transform that defines * the satellite frame with respect to its parent GCRF frame. This * is the purpose of this method. This update is done by the following call, * where measurementTransform represents the measurement as a * simple translation transform between the two antenna frames:

*

     * satellite.updateTransform(onBoardAntenna, trackingAntenna,
     *                           measurementTransform, date);
     * 
*

One way to represent the behavior of the method is to consider the * sub-tree rooted at the instance on one hand (satellite and on-board antenna * in the example above) and the tree containing all the other frames on the * other hand (GCRF, Sun, Earth, ground station, tracking antenna). * Both tree are considered as two solid sets linked together by a flexible * spring, which is the transform we want to update. The method stretches the * spring to make sure the transform between the two specified frames (one in * each tree part) matches the specified transform.

* @param f1 first control frame (may be the instance itself) * @param f2 second control frame (may be the instance itself) * @param f1Tof2 desired transform from first to second control frame * @param date date of the transform */ public void updateTransform(final Frame f1, final Frame f2, final Transform f1Tof2, final AbsoluteDate date) { Frame fA = f1; Frame fB = f2; Transform fAtoB = f1Tof2; // make sure f1 is not a child of the instance if (fA.isChildOf(this) || (fA == this)) { if (fB.isChildOf(this) || (fB == this)) { throw new FrameAncestorException(OrekitMessages.FRAME_ANCESTOR_OF_BOTH_FRAMES, getName(), fA.getName(), fB.getName()); } // swap f1 and f2 to make sure the child is f2 final Frame tmp = fA; fA = fB; fB = tmp; fAtoB = fAtoB.getInverse(); } else if (!(fB.isChildOf(this) || (fB == this))) { throw new FrameAncestorException(OrekitMessages.FRAME_ANCESTOR_OF_NEITHER_FRAME, getName(), fA.getName(), fB.getName()); } // rebuild the transform by traveling from parent to self // WITHOUT using the existing provider from parent to self that will be updated final Transform parentTofA = getParent().getTransformTo(fA, date); final Transform fBtoSelf = fB.getTransformTo(this, date); final Transform fAtoSelf = new Transform(date, fAtoB, fBtoSelf); final Transform parentToSelf = new Transform(date, parentTofA, fAtoSelf); // update the existing provider from parent to self ((UpdatableProvider) getTransformProvider()).setTransform(parentToSelf); } /** Local provider for transforms. */ private static class UpdatableProvider implements TransformProvider { /** Serializable UID. */ private static final long serialVersionUID = 4436954500689776331L; /** Current transform. */ private AtomicReference transform; /** Simple constructor. * @param transform initial value of the transform */ UpdatableProvider(final Transform transform) { this.transform = new AtomicReference(transform); } /** Update the transform from the parent frame to the instance. * @param transform new transform from parent frame to instance */ public void setTransform(final Transform transform) { this.transform.set(transform); } /** {@inheritDoc} */ public Transform getTransform(final AbsoluteDate date) { return transform.get(); } /** {@inheritDoc} */ @Override public > FieldTransform getTransform(final FieldAbsoluteDate date) { return new FieldTransform<>(date.getField(), transform.get()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy