1 /* Copyright 2002-2019 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.frames; 18 19 import org.hipparchus.Field; 20 import org.hipparchus.RealFieldElement; 21 import org.hipparchus.geometry.euclidean.threed.FieldRotation; 22 import org.hipparchus.geometry.euclidean.threed.FieldVector3D; 23 import org.hipparchus.geometry.euclidean.threed.Rotation; 24 import org.hipparchus.geometry.euclidean.threed.Vector3D; 25 import org.orekit.time.AbsoluteDate; 26 import org.orekit.time.FieldAbsoluteDate; 27 import org.orekit.utils.FieldPVCoordinates; 28 import org.orekit.utils.PVCoordinates; 29 30 /** Enumerate for different types of Local Orbital Frames. 31 * @author Luc Maisonobe 32 */ 33 public enum LOFType { 34 35 /** Constant for TNW frame 36 * (X axis aligned with velocity, Z axis aligned with orbital momentum). 37 * <p> 38 * The axes of this frame are parallel to the axes of the {@link #VNC} frame: 39 * <ul> 40 * <li>X<sub>TNW</sub> = X<sub>VNC</sub></li> 41 * <li>Y<sub>TNW</sub> = -Z<sub>VNC</sub></li> 42 * <li>Z<sub>TNW</sub> = Y<sub>VNC</sub></li> 43 * </ul> 44 * 45 * @see #VNC 46 */ 47 TNW { 48 49 /** {@inheritDoc} */ 50 public Rotation rotationFromInertial(final PVCoordinates pv) { 51 return new Rotation(pv.getVelocity(), pv.getMomentum(), 52 Vector3D.PLUS_I, Vector3D.PLUS_K); 53 } 54 55 /** {@inheritDoc} */ 56 public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field, 57 final FieldPVCoordinates<T> pv) { 58 return new FieldRotation<>(pv.getVelocity(), pv.getMomentum(), 59 new FieldVector3D<>(field, Vector3D.PLUS_I), 60 new FieldVector3D<>(field, Vector3D.PLUS_K)); 61 } 62 63 }, 64 65 /** Constant for QSW frame 66 * (X axis aligned with position, Z axis aligned with orbital momentum). 67 * <p> 68 * This frame is also known as the {@link #LVLH} frame, both constants are equivalent. 69 * </p> 70 * <p> 71 * The axes of these frames are parallel to the axes of the {@link #VVLH} frame: 72 * <ul> 73 * <li>X<sub>QSW/LVLH</sub> = -Z<sub>VVLH</sub></li> 74 * <li>Y<sub>QSW/LVLH</sub> = X<sub>VVLH</sub></li> 75 * <li>Z<sub>QSW/LVLH</sub> = -Y<sub>VVLH</sub></li> 76 * </ul> 77 * 78 * @see #LVLH 79 * @see #VVLH 80 */ 81 QSW { 82 83 /** {@inheritDoc} */ 84 public Rotation rotationFromInertial(final PVCoordinates pv) { 85 return new Rotation(pv.getPosition(), pv.getMomentum(), 86 Vector3D.PLUS_I, Vector3D.PLUS_K); 87 } 88 89 /** {@inheritDoc} */ 90 public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field, 91 final FieldPVCoordinates<T> pv) { 92 return new FieldRotation<>(pv.getPosition(), pv.getMomentum(), 93 new FieldVector3D<>(field, Vector3D.PLUS_I), 94 new FieldVector3D<>(field, Vector3D.PLUS_K)); 95 } 96 97 }, 98 99 /** Constant for Local Vertical, Local Horizontal frame 100 * (X axis aligned with position, Z axis aligned with orbital momentum). 101 * <p> 102 * This frame is also known as the {@link #QSW} frame, both constants are equivalent. 103 * </p> 104 * <p> 105 * The axes of these frames are parallel to the axes of the {@link #VVLH} frame: 106 * <ul> 107 * <li>X<sub>LVLH/QSW</sub> = -Z<sub>VVLH</sub></li> 108 * <li>Y<sub>LVLH/QSW</sub> = X<sub>VVLH</sub></li> 109 * <li>Z<sub>LVLH/QSW</sub> = -Y<sub>VVLH</sub></li> 110 * </ul> 111 * 112 * @see #QSW 113 * @see #VVLH 114 */ 115 LVLH { 116 117 /** {@inheritDoc} */ 118 public Rotation rotationFromInertial(final PVCoordinates pv) { 119 return new Rotation(pv.getPosition(), pv.getMomentum(), 120 Vector3D.PLUS_I, Vector3D.PLUS_K); 121 } 122 123 /** {@inheritDoc} */ 124 public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field, 125 final FieldPVCoordinates<T> pv) { 126 return new FieldRotation<>(pv.getPosition(), pv.getMomentum(), 127 new FieldVector3D<>(field, Vector3D.PLUS_I), 128 new FieldVector3D<>(field, Vector3D.PLUS_K)); 129 } 130 131 }, 132 133 /** Constant for Vehicle Velocity, Local Horizontal frame 134 * (Z axis aligned with opposite of position, Y axis aligned with opposite of orbital momentum). 135 * <p> 136 * The axes of this frame are parallel to the axes of both the {@link #QSW} and {@link #LVLH} frames: 137 * <ul> 138 * <li>X<sub>VVLH</sub> = Y<sub>QSW/LVLH</sub></li> 139 * <li>Y<sub>VVLH</sub> = -Z<sub>QSW/LVLH</sub></li> 140 * <li>Z<sub>VVLH</sub> = -X<sub>QSW/LVLH</sub></li> 141 * </ul> 142 * 143 * @see #QSW 144 * @see #LVLH 145 */ 146 VVLH { 147 148 /** {@inheritDoc} */ 149 public Rotation rotationFromInertial(final PVCoordinates pv) { 150 return new Rotation(pv.getPosition(), pv.getMomentum(), 151 Vector3D.MINUS_K, Vector3D.MINUS_J); 152 } 153 154 /** {@inheritDoc} */ 155 public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field, 156 final FieldPVCoordinates<T> pv) { 157 return new FieldRotation<>(pv.getPosition(), pv.getMomentum(), 158 new FieldVector3D<>(field, Vector3D.MINUS_K), 159 new FieldVector3D<>(field, Vector3D.MINUS_J)); 160 } 161 162 }, 163 164 /** Constant for Velocity - Normal - Co-normal frame 165 * (X axis aligned with velocity, Y axis aligned with orbital momentum). 166 * <p> 167 * The axes of this frame are parallel to the axes of the {@link #TNW} frame: 168 * <ul> 169 * <li>X<sub>VNC</sub> = X<sub>TNW</sub></li> 170 * <li>Y<sub>VNC</sub> = Z<sub>TNW</sub></li> 171 * <li>Z<sub>VNC</sub> = -Y<sub>TNW</sub></li> 172 * </ul> 173 * 174 * @see #TNW 175 */ 176 VNC { 177 178 /** {@inheritDoc} */ 179 public Rotation rotationFromInertial(final PVCoordinates pv) { 180 return new Rotation(pv.getVelocity(), pv.getMomentum(), 181 Vector3D.PLUS_I, Vector3D.PLUS_J); 182 } 183 184 @Override 185 public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field, 186 final FieldPVCoordinates<T> pv) { 187 return new FieldRotation<>(pv.getVelocity(), pv.getMomentum(), 188 new FieldVector3D<>(field, Vector3D.PLUS_I), 189 new FieldVector3D<>(field, Vector3D.PLUS_J)); 190 } 191 192 }; 193 194 /** Get the transform from an inertial frame defining position-velocity and the local orbital frame. 195 * @param date current date 196 * @param pv position-velocity of the spacecraft in some inertial frame 197 * @return transform from the frame where position-velocity are defined to local orbital frame 198 */ 199 public Transform transformFromInertial(final AbsoluteDate date, final PVCoordinates pv) { 200 201 // compute the translation part of the transform 202 final Transformorm">Transform translation = new Transform(date, pv.negate()); 203 204 // compute the rotation part of the transform 205 final Rotation r = rotationFromInertial(pv); 206 final Vector3D p = pv.getPosition(); 207 final Vector3D momentum = pv.getMomentum(); 208 final Transform rotation = 209 new Transform(date, r, new Vector3D(1.0 / p.getNormSq(), r.applyTo(momentum))); 210 211 return new Transform(date, translation, rotation); 212 213 } 214 215 /** Get the transform from an inertial frame defining position-velocity and the local orbital frame. 216 * @param date current date 217 * @param pv position-velocity of the spacecraft in some inertial frame 218 * @param <T> type of the fiels elements 219 * @return transform from the frame where position-velocity are defined to local orbital frame 220 * @since 9.0 221 */ 222 public <T extends RealFieldElement<T>> FieldTransform<T> transformFromInertial(final FieldAbsoluteDate<T> date, 223 final FieldPVCoordinates<T> pv) { 224 225 // compute the translation part of the transform 226 final FieldTransform<T> translation = new FieldTransform<>(date, pv.negate()); 227 228 // compute the rotation part of the transform 229 final FieldRotation<T> r = rotationFromInertial(date.getField(), pv); 230 final FieldVector3D<T> p = pv.getPosition(); 231 final FieldVector3D<T> momentum = pv.getMomentum(); 232 final FieldTransform<T> rotation = 233 new FieldTransform<T>(date, r, new FieldVector3D<>(p.getNormSq().reciprocal(), r.applyTo(momentum))); 234 235 return new FieldTransform<>(date, translation, rotation); 236 237 } 238 239 /** Get the rotation from inertial frame to local orbital frame. 240 * <p> 241 * This rotation does not include any time derivatives. If first 242 * time derivatives (i.e. rotation rate) is needed as well, the full 243 * {@link #transformFromInertial(AbsoluteDate, PVCoordinates) transformFromInertial} 244 * method must be called and the complete rotation transform must be extracted 245 * from it. 246 * </p> 247 * @param pv position-velocity of the spacecraft in some inertial frame 248 * @return rotation from inertial frame to local orbital frame 249 */ 250 public abstract Rotation rotationFromInertial(PVCoordinates pv); 251 252 /** Get the rotation from inertial frame to local orbital frame. 253 * <p> 254 * This rotation does not include any time derivatives. If first 255 * time derivatives (i.e. rotation rate) is needed as well, the full 256 * {@link #transformFromInertial(FieldAbsoluteDate, FieldPVCoordinates) transformFromInertial} 257 * method must be called and the complete rotation transform must be extracted 258 * from it. 259 * </p> 260 * @param field field to which the elements belong 261 * @param pv position-velocity of the spacecraft in some inertial frame 262 * @param <T> type of the field elements 263 * @return rotation from inertial frame to local orbital frame 264 * @since 9.0 265 */ 266 public abstract <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(Field<T> field, 267 FieldPVCoordinates<T> pv); 268 269 }