1 /* Copyright 2002-2013 CS Systèmes d'Information 2 * Licensed to CS Systèmes d'Information (CS) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * CS licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.orekit.attitudes; 18 19 import org.apache.commons.math3.geometry.euclidean.threed.Rotation; 20 import org.apache.commons.math3.geometry.euclidean.threed.RotationOrder; 21 import org.orekit.errors.OrekitException; 22 import org.orekit.errors.OrekitMessages; 23 import org.orekit.frames.Frame; 24 import org.orekit.frames.LOFType; 25 import org.orekit.frames.Transform; 26 import org.orekit.time.AbsoluteDate; 27 import org.orekit.utils.PVCoordinates; 28 import org.orekit.utils.PVCoordinatesProvider; 29 30 31 /** 32 * Attitude law defined by fixed Roll, Pitch and Yaw angles (in any order) 33 * with respect to a local orbital frame. 34 35 * <p> 36 * The attitude provider is defined as a rotation offset from some local orbital frame. 37 * @author Véronique Pommier-Maurussane 38 */ 39 public class LofOffset implements AttitudeProvider { 40 41 /** Serializable UID. */ 42 private static final long serialVersionUID = -713570668596014285L; 43 44 /** Type of Local Orbital Frame. */ 45 private LOFType type; 46 47 /** Rotation from local orbital frame. */ 48 private final Rotation offset; 49 50 /** Inertial frame with respect to which orbit should be computed. */ 51 private final Frame inertialFrame; 52 53 /** Create a LOF-aligned attitude. 54 * <p> 55 * Calling this constructor is equivalent to call 56 * {@code LofOffset(intertialFrame, LOFType.VVLH)} 57 * </p> 58 * @param inertialFrame inertial frame with respect to which orbit should be computed 59 * @exception OrekitException if inertialFrame is not a pseudo-inertial frame 60 * @deprecated as of 6.0 replaced by {@link #LofOffset(Frame, LOFType)} 61 */ 62 @Deprecated 63 public LofOffset(final Frame inertialFrame) throws OrekitException { 64 this(inertialFrame, LOFType.VVLH); 65 } 66 67 /** Creates new instance. 68 * <p> 69 * Calling this constructor is equivalent to call 70 * {@code LofOffset(intertialFrame, LOFType.VVLH, order, alpha1, alpha2, alpha3)} 71 * </p> 72 * @param inertialFrame inertial frame with respect to which orbit should be computed 73 * @param order order of rotations to use for (alpha1, alpha2, alpha3) composition 74 * @param alpha1 angle of the first elementary rotation 75 * @param alpha2 angle of the second elementary rotation 76 * @param alpha3 angle of the third elementary rotation 77 * @exception OrekitException if inertialFrame is not a pseudo-inertial frame 78 * @deprecated as of 6.0 replaced by {@link #LofOffset(Frame, LOFType, RotationOrder, double, double, double)} 79 */ 80 @Deprecated 81 public LofOffset(final Frame inertialFrame, 82 final RotationOrder order, final double alpha1, 83 final double alpha2, final double alpha3) throws OrekitException { 84 this(inertialFrame, LOFType.VVLH, order, alpha1, alpha2, alpha3); 85 } 86 87 /** Create a LOF-aligned attitude. 88 * <p> 89 * Calling this constructor is equivalent to call 90 * {@code LofOffset(inertialFrame, LOFType, RotationOrder.XYZ, 0, 0, 0)} 91 * </p> 92 * @param inertialFrame inertial frame with respect to which orbit should be computed 93 * @param type type of Local Orbital Frame 94 * @exception OrekitException if inertialFrame is not a pseudo-inertial frame 95 */ 96 public LofOffset(final Frame inertialFrame, final LOFType type) throws OrekitException { 97 this(inertialFrame, type, RotationOrder.XYZ, 0, 0, 0); 98 } 99 100 /** Creates new instance. 101 * <p> 102 * An important thing to note is that the rotation order and angles signs used here 103 * are compliant with an <em>attitude</em> definition, i.e. they correspond to 104 * a frame that rotate in a field of fixed vectors. The underlying definitions used 105 * in commons-math {@link org.apache.commons.math3.geometry.euclidean.threed.Rotation#Rotation(RotationOrder, 106 * double, double, double) Rotation(RotationOrder, double, double, double)} use 107 * <em>reversed</em> definition, i.e. they correspond to a vectors field rotating 108 * with respect to a fixed frame. So to retrieve the angles provided here from the 109 * commons-math underlying rotation, one has to <em>revert</em> the rotation, as in 110 * the following code snippet: 111 * </p> 112 * <pre> 113 * LofOffset law = new LofOffset(inertial, lofType, order, alpha1, alpha2, alpha3); 114 * Rotation offsetAtt = law.getAttitude(orbit).getRotation(); 115 * Rotation alignedAtt = new LofOffset(inertial, lofType).getAttitude(orbit).getRotation(); 116 * Rotation offsetProper = offsetAtt.applyTo(alignedAtt.revert()); 117 * 118 * // note the call to revert in the following statement 119 * double[] angles = offsetProper.revert().getAngles(order); 120 * 121 * System.out.println(alpha1 + " == " + angles[0]); 122 * System.out.println(alpha2 + " == " + angles[1]); 123 * System.out.println(alpha3 + " == " + angles[2]); 124 * </pre> 125 * @param inertialFrame inertial frame with respect to which orbit should be computed 126 * @param type type of Local Orbital Frame 127 * @param order order of rotations to use for (alpha1, alpha2, alpha3) composition 128 * @param alpha1 angle of the first elementary rotation 129 * @param alpha2 angle of the second elementary rotation 130 * @param alpha3 angle of the third elementary rotation 131 * @exception OrekitException if inertialFrame is not a pseudo-inertial frame 132 */ 133 public LofOffset(final Frame inertialFrame, final LOFType type, 134 final RotationOrder order, final double alpha1, 135 final double alpha2, final double alpha3) throws OrekitException { 136 this.type = type; 137 this.offset = new Rotation(order, alpha1, alpha2, alpha3).revert(); 138 if (!inertialFrame.isPseudoInertial()) { 139 throw new OrekitException(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME_NOT_SUITABLE_FOR_DEFINING_ORBITS, 140 inertialFrame.getName()); 141 } 142 this.inertialFrame = inertialFrame; 143 } 144 145 146 /** {@inheritDoc} */ 147 public Attitude getAttitude(final PVCoordinatesProvider pvProv, 148 final AbsoluteDate date, final Frame frame) 149 throws OrekitException { 150 151 // construction of the local orbital frame, using PV from inertial frame 152 final PVCoordinates pv = pvProv.getPVCoordinates(date, inertialFrame); 153 final Transform inertialToLof = type.transformFromInertial(date, pv); 154 155 // take into account the specified start frame (which may not be an inertial one) 156 final Transform frameToInertial = frame.getTransformTo(inertialFrame, date); 157 final Transform frameToLof = new Transform(date, frameToInertial, inertialToLof); 158 159 // compose with offset rotation 160 return new Attitude(date, frame, 161 offset.applyTo(frameToLof.getRotation()), 162 offset.applyTo(frameToLof.getRotationRate())); 163 164 } 165 166 }