1   /* Copyright 2002-2021 CS GROUP
2    * Licensed to CS GROUP (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.geometry.euclidean.threed.Vector3D;
20  import org.junit.Assert;
21  import org.junit.Before;
22  import org.junit.Test;
23  import org.orekit.orbits.KeplerianOrbit;
24  import org.orekit.orbits.Orbit;
25  import org.orekit.orbits.PositionAngle;
26  import org.orekit.propagation.analytical.KeplerianPropagator;
27  import org.orekit.time.AbsoluteDate;
28  import org.orekit.utils.PVCoordinates;
29  import org.orekit.utils.PVCoordinatesProvider;
30  
31  public class LocalOrbitalFrameTest {
32  
33      @Test
34      public void testTNW() {
35          AbsoluteDate date = initDate.shiftedBy(400);
36          PVCoordinates pv = provider.getPVCoordinates(date, inertialFrame);
37          checkFrame(LOFType.TNW, date,
38                     pv.getVelocity(),
39                     Vector3D.crossProduct(pv.getMomentum(), pv.getVelocity()),
40                     pv.getMomentum(),
41                     pv.getMomentum().negate());
42      }
43  
44      @Test
45      public void testQSW() {
46          AbsoluteDate date = initDate.shiftedBy(400);
47          PVCoordinates pv = provider.getPVCoordinates(date, inertialFrame);
48          checkFrame(LOFType.QSW, date,
49                     pv.getPosition(),
50                     Vector3D.crossProduct(pv.getMomentum(), pv.getPosition()),
51                     pv.getMomentum(),
52                     pv.getMomentum().negate());
53      }
54  
55      @Test
56      public void testLVLH() {
57          AbsoluteDate date = initDate.shiftedBy(400);
58          PVCoordinates pv = provider.getPVCoordinates(date, inertialFrame);
59          checkFrame(LOFType.LVLH, date,
60                     pv.getPosition(),
61                     Vector3D.crossProduct(pv.getMomentum(), pv.getPosition()),
62                     pv.getMomentum(),
63                     pv.getMomentum().negate());
64      }
65  
66      @Test
67      public void testLVLH_CCSDS() {
68          AbsoluteDate date = initDate.shiftedBy(400);
69          PVCoordinates pv = provider.getPVCoordinates(date, inertialFrame);
70          checkFrame(LOFType.LVLH_CCSDS, date,
71                     Vector3D.crossProduct(pv.getMomentum(), pv.getPosition()),
72                     pv.getMomentum().negate(),
73                     pv.getPosition().negate(),
74                     pv.getMomentum().negate());
75      }
76  
77      @Test
78      public void testVVLH() {
79          AbsoluteDate date = initDate.shiftedBy(400);
80          PVCoordinates pv = provider.getPVCoordinates(date, inertialFrame);
81          checkFrame(LOFType.VVLH, date,
82                     Vector3D.crossProduct(pv.getMomentum(), pv.getPosition()),
83                     pv.getMomentum().negate(),
84                     pv.getPosition().negate(),
85                     pv.getMomentum().negate());
86      }
87  
88      @Test
89      public void testVNC() {
90          AbsoluteDate date = initDate.shiftedBy(400);
91          PVCoordinates pv = provider.getPVCoordinates(date, inertialFrame);
92          checkFrame(LOFType.VNC, date,
93                     pv.getVelocity(),
94                     pv.getMomentum(),
95                     Vector3D.crossProduct(pv.getVelocity(), pv.getMomentum()),
96                     pv.getMomentum().negate());
97      }
98  
99      private void checkFrame(LOFType type, AbsoluteDate date,
100                             Vector3D expectedXDirection, Vector3D expectedYDirection,
101                             Vector3D expectedZDirection, Vector3D expectedRotationDirection)
102         {
103         LocalOrbitalFrame lof = new LocalOrbitalFrame(FramesFactory.getGCRF(), type, provider, type.name());
104 
105         Transform t = lof.getTransformTo(FramesFactory.getGCRF(), date);
106         PVCoordinates pv1 = t.transformPVCoordinates(PVCoordinates.ZERO);
107         Vector3D p1 = pv1.getPosition();
108         Vector3D v1 = pv1.getVelocity();
109         PVCoordinates pv2 = provider.getPVCoordinates(date, FramesFactory.getGCRF());
110         Vector3D p2 = pv2.getPosition();
111         Vector3D v2 = pv2.getVelocity();
112         Assert.assertEquals(0, p1.subtract(p2).getNorm(), 1.0e-14 * p1.getNorm());
113         Assert.assertEquals(0, v1.subtract(v2).getNorm(), 1.0e-14 * v1.getNorm());
114 
115         Vector3D xDirection = t.transformVector(Vector3D.PLUS_I);
116         Vector3D yDirection = t.transformVector(Vector3D.PLUS_J);
117         Vector3D zDirection = t.transformVector(Vector3D.PLUS_K);
118         Assert.assertEquals(0, Vector3D.angle(expectedXDirection, xDirection), 2.0e-15);
119         Assert.assertEquals(0, Vector3D.angle(expectedYDirection, yDirection), 1.0e-15);
120         Assert.assertEquals(0, Vector3D.angle(expectedZDirection, zDirection), 1.0e-15);
121         Assert.assertEquals(0, Vector3D.angle(expectedRotationDirection, t.getRotationRate()), 1.0e-15);
122 
123         Assert.assertEquals(initialOrbit.getKeplerianMeanMotion(), t.getRotationRate().getNorm(), 1.0e-7);
124 
125     }
126 
127     @Before
128     public void setUp() {
129         inertialFrame = FramesFactory.getGCRF();
130         initDate = AbsoluteDate.J2000_EPOCH.shiftedBy(584.);
131         initialOrbit =
132                 new KeplerianOrbit(7209668.0, 0.5e-4, 1.7, 2.1, 2.9, 6.2, PositionAngle.TRUE,
133                                    inertialFrame, initDate, 3.986004415e14);
134         provider = new KeplerianPropagator(initialOrbit);
135 
136     }
137 
138     private Frame                                 inertialFrame;
139     private AbsoluteDate                          initDate;
140     private Orbit                                 initialOrbit;
141     private PVCoordinatesProvider                 provider;
142 
143 }