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 }