1   /* Copyright 2002-2022 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.orbits;
18  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
21  import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
22  import org.junit.Assert;
23  import org.junit.Before;
24  import org.junit.Test;
25  import org.orekit.Utils;
26  import org.orekit.bodies.CR3BPFactory;
27  import org.orekit.bodies.CR3BPSystem;
28  import org.orekit.errors.OrekitException;
29  import org.orekit.frames.Frame;
30  import org.orekit.propagation.SpacecraftState;
31  import org.orekit.propagation.numerical.NumericalPropagator;
32  import org.orekit.propagation.numerical.cr3bp.CR3BPForceModel;
33  import org.orekit.propagation.numerical.cr3bp.STMEquations;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.time.TimeScalesFactory;
36  import org.orekit.utils.AbsolutePVCoordinates;
37  import org.orekit.utils.LagrangianPoints;
38  import org.orekit.utils.PVCoordinates;
39  
40  public class LyapunovOrbitTest {
41  
42      
43      @Test
44      public void testLyapunovOrbit() {
45      	CR3BPSystem syst = CR3BPFactory.getEarthMoonCR3BP();
46      
47  	    final PVCoordinates firstGuess = new PVCoordinates(new Vector3D(0.0, 1.0, 2.0), new Vector3D(3.0, 4.0, 5.0));
48  	    final LyapunovOrbit h1 = new LyapunovOrbit(new RichardsonExpansion(syst, LagrangianPoints.L1), 8E6);
49  	    final LyapunovOrbit h2 = new LyapunovOrbit(syst, firstGuess, 2.0);
50  	    final LyapunovOrbit h3 = new LyapunovOrbit(new RichardsonExpansion(syst, LagrangianPoints.L2), 8E6);
51  
52  	    final double orbitalPeriod1 = h1.getOrbitalPeriod();
53  	    final double orbitalPeriod2 = h2.getOrbitalPeriod();
54  	    final double orbitalPeriod3 = h3.getOrbitalPeriod();
55      
56  	    final PVCoordinates firstGuess1 = h1.getInitialPV();
57  	    final PVCoordinates firstGuess2 = h2.getInitialPV();
58  	    final PVCoordinates firstGuess3 = h3.getInitialPV();
59      
60  	    Assert.assertNotEquals(0.0, orbitalPeriod1, 0.5);
61  	    Assert.assertNotEquals(0.0, orbitalPeriod3, 0.5);
62  	    Assert.assertEquals(2.0, orbitalPeriod2, 1E-15);
63      
64  	    Assert.assertNotEquals(0.0, firstGuess1.getPosition().getX(), 0.6);
65  	    Assert.assertEquals(0.0, firstGuess1.getPosition().getY(), 1E-15);
66  	    Assert.assertEquals(0.0, firstGuess1.getVelocity().getX(), 1E-15);
67  	    Assert.assertNotEquals(0.0, firstGuess1.getVelocity().getY(), 0.01);
68  	    Assert.assertEquals(0.0, firstGuess1.getVelocity().getZ(), 1E-15);
69      
70  	    Assert.assertNotEquals(0.0, firstGuess3.getPosition().getX(), 1);
71  	    Assert.assertEquals(0.0, firstGuess3.getPosition().getY(), 1E-15);
72  	    Assert.assertEquals(0.0, firstGuess3.getVelocity().getX(), 1E-15);
73  	    Assert.assertNotEquals(0.0, firstGuess3.getVelocity().getY(), 0.01);
74  	    Assert.assertEquals(0.0, firstGuess3.getVelocity().getZ(), 1E-15);
75      
76  	    Assert.assertEquals(firstGuess.getPosition().getX(), firstGuess2.getPosition().getX(), 1E-15);
77  	    Assert.assertEquals(firstGuess.getPosition().getY(), firstGuess2.getPosition().getY(), 1E-15);
78  	    Assert.assertEquals(firstGuess.getPosition().getZ(), firstGuess2.getPosition().getZ(), 1E-15);
79  	    Assert.assertEquals(firstGuess.getVelocity().getX(), firstGuess2.getVelocity().getX(), 1E-15);
80  	    Assert.assertEquals(firstGuess.getVelocity().getY(), firstGuess2.getVelocity().getY(), 1E-15);
81  	    Assert.assertEquals(firstGuess.getVelocity().getZ(), firstGuess2.getVelocity().getZ(), 1E-15);
82      }
83      
84      @Test(expected=OrekitException.class)
85  	    public void testLagrangianError() {
86  	    CR3BPSystem syst = CR3BPFactory.getEarthMoonCR3BP();
87  	    final HaloOrbit h = new HaloOrbit(new RichardsonExpansion(syst, LagrangianPoints.L3), 8E6, LibrationOrbitFamily.NORTHERN);
88  	    h.getClass();
89      }
90      
91      @Test
92      public void testManifolds() {
93  
94          // Time settings
95          final AbsoluteDate initialDate =
96              new AbsoluteDate(1996, 06, 25, 0, 0, 00.000,
97                               TimeScalesFactory.getUTC());
98          CR3BPSystem syst = CR3BPFactory.getEarthMoonCR3BP();
99  
100         final Frame Frame = syst.getRotatingFrame();
101 
102         LyapunovOrbit h = new LyapunovOrbit(new RichardsonExpansion(syst, LagrangianPoints.L1), 8E6);
103         h.applyDifferentialCorrection();
104         final double orbitalPeriod = h.getOrbitalPeriod();
105         double integrationTime = orbitalPeriod * 0.1;
106         final PVCoordinates initialConditions = h.getInitialPV();
107 
108         final AbsolutePVCoordinates initialAbsPV =
109             new AbsolutePVCoordinates(Frame, initialDate, initialConditions);
110 
111         // Creating the initial spacecraftstate that will be given to the
112         // propagator
113         final SpacecraftState initialState = new SpacecraftState(initialAbsPV);
114         
115         // Integration parameters
116         // These parameters are used for the Dormand-Prince integrator, a
117         // variable step integrator,
118         // these limits prevent the integrator to spend too much time when the
119         // equations are too stiff,
120         // as well as the reverse situation.
121         final double minStep = 1E-10;
122         final double maxstep = 1E-2;
123 
124         // tolerances for integrators
125         // Used by the integrator to estimate its variable integration step
126         final double positionTolerance = 0.0001;
127         final double velocityTolerance = 0.0001;
128         final double massTolerance = 1.0e-6;
129         final double[] vecAbsoluteTolerances = { positionTolerance, positionTolerance, positionTolerance,
130                 velocityTolerance, velocityTolerance, velocityTolerance, massTolerance };
131         final double[] vecRelativeTolerances = new double[vecAbsoluteTolerances.length];
132 
133         // Defining the numerical integrator that will be used by the propagator
134         AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(minStep, maxstep, vecAbsoluteTolerances,
135                 vecRelativeTolerances);
136 
137         final STMEquations stm = new STMEquations(syst);
138         final SpacecraftState augmentedInitialState =
139                         stm.setInitialPhi(initialState);
140         NumericalPropagator propagator = new NumericalPropagator(integrator);
141         propagator.setOrbitType(null);
142         propagator.setIgnoreCentralAttraction(true);
143         propagator.addForceModel(new CR3BPForceModel(syst));
144         propagator.addAdditionalDerivativesProvider(stm);
145         propagator.setInitialState(augmentedInitialState);
146         final SpacecraftState finalState = propagator.propagate(initialDate.shiftedBy(integrationTime));
147         
148         final PVCoordinates initialUnstableManifold = h.getManifolds(finalState, false);
149         final PVCoordinates initialStableManifold = h.getManifolds(finalState, true);
150         
151         Assert.assertNotEquals(finalState.getPVCoordinates().getPosition().getX(), initialUnstableManifold.getPosition().getX(), 1E-7);
152         Assert.assertNotEquals(finalState.getPVCoordinates().getPosition().getY(), initialUnstableManifold.getPosition().getY(), 1E-7);
153         
154         Assert.assertNotEquals(finalState.getPVCoordinates().getPosition().getX(), initialStableManifold.getPosition().getX(), 1E-7);
155         Assert.assertNotEquals(finalState.getPVCoordinates().getPosition().getY(), initialStableManifold.getPosition().getY(), 1E-7);
156     }
157     
158     @Test(expected=OrekitException.class)
159     public void testDifferentialCorrectionError() {
160 
161         CR3BPSystem syst = CR3BPFactory.getEarthMoonCR3BP();
162 
163         final double orbitalPeriod = 1;
164 
165         final PVCoordinates firstGuess = new PVCoordinates(new Vector3D(0.0, 1.0, 2.0), new Vector3D(3.0, 4.0, 5.0));
166 
167         final PVCoordinates initialConditions =
168             new CR3BPDifferentialCorrection(firstGuess, syst, orbitalPeriod).compute(LibrationOrbitType.LYAPUNOV);
169         initialConditions.toString();
170     }
171     
172     @Test(expected=OrekitException.class)
173     public void testSTMError() {
174         // Time settings
175         final AbsoluteDate initialDate =
176                         new AbsoluteDate(1996, 06, 25, 0, 0, 00.000,
177                                          TimeScalesFactory.getUTC());
178         CR3BPSystem syst = CR3BPFactory.getEarthMoonCR3BP();
179 
180         final Frame Frame = syst.getRotatingFrame();
181 
182         // Define a Northern Halo orbit around Earth-Moon L1 with a Z-amplitude
183         // of 8 000 km
184         LyapunovOrbit h = new LyapunovOrbit(new RichardsonExpansion(syst, LagrangianPoints.L1), 8E6);
185 
186         final PVCoordinates pv = new PVCoordinates(new Vector3D(0.0, 1.0, 2.0), new Vector3D(3.0, 4.0, 5.0));
187 
188         final AbsolutePVCoordinates initialAbsPV =
189                         new AbsolutePVCoordinates(Frame, initialDate, pv);
190 
191         // Creating the initial spacecraftstate that will be given to the
192         // propagator
193         final SpacecraftState s = new SpacecraftState(initialAbsPV);
194 
195         final PVCoordinates manifold = h.getManifolds(s, true);
196         manifold.getMomentum();
197     }
198     
199     @Before
200     public void setUp() {
201         Utils.setDataRoot("cr3bp:regular-data");
202     }
203 }