1   /* Copyright 2022-2025 Romain Serra
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.forces.maneuvers;
18  
19  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
20  import org.hipparchus.geometry.euclidean.threed.Vector3D;
21  import org.hipparchus.util.Binary64;
22  import org.hipparchus.util.Binary64Field;
23  import org.junit.jupiter.api.Assertions;
24  import org.junit.jupiter.api.Test;
25  import org.junit.jupiter.params.ParameterizedTest;
26  import org.junit.jupiter.params.provider.ValueSource;
27  import org.orekit.TestUtils;
28  import org.orekit.frames.FramesFactory;
29  import org.orekit.orbits.CartesianOrbit;
30  import org.orekit.orbits.FieldCartesianOrbit;
31  import org.orekit.orbits.Orbit;
32  import org.orekit.propagation.FieldSpacecraftState;
33  import org.orekit.propagation.SpacecraftState;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.time.FieldAbsoluteDate;
36  import org.orekit.utils.PVCoordinates;
37  
38  class FieldImpulseProviderTest {
39  
40      @Test
41      void testOfVector3D() {
42          // GIVEN
43          final Vector3D forwardImpulse = new Vector3D(1, 2, 3);
44          final Binary64Field field = Binary64Field.getInstance();
45          final FieldImpulseProvider<Binary64> provider = FieldImpulseProvider.of(field, forwardImpulse);
46          // WHEN
47          final Vector3D vector3D = provider.getImpulse(null, true).toVector3D();
48          // THEN
49          Assertions.assertEquals(forwardImpulse, vector3D);
50          Assertions.assertEquals(forwardImpulse.negate(), provider.getImpulse(null, false).toVector3D());
51      }
52  
53      @Test
54      void testOfFieldVector3D() {
55          // GIVEN
56          final Vector3D forwardImpulse = new Vector3D(1, 2, 3);
57          final Binary64Field field = Binary64Field.getInstance();
58          final Orbit orbit = TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH);
59          final SpacecraftState state = new SpacecraftState(orbit).withMass(100);
60          final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
61          // WHEN
62          final FieldImpulseProvider<Binary64> provider = FieldImpulseProvider.of(new FieldVector3D<>(field, forwardImpulse));
63          final Vector3D vector3D = provider.getImpulse(fieldState, true).toVector3D();
64          // THEN
65          Assertions.assertEquals(forwardImpulse, vector3D);
66          Assertions.assertEquals(forwardImpulse.negate(), provider.getImpulse(fieldState, false).toVector3D());
67      }
68  
69      @ParameterizedTest
70      @ValueSource(booleans = {true, false})
71      void testOfImpulseProvider(final boolean isForward) {
72          // GIVEN
73          final Vector3D forwardImpulse = new Vector3D(1, 2, 3);
74          final ImpulseProvider impulseProvider = ImpulseProvider.of(forwardImpulse);
75          final FieldImpulseProvider<Binary64> fieldImpulseProvider = FieldImpulseProvider.of(impulseProvider);
76          final FieldSpacecraftState<Binary64> fieldSpacecraftState = buildFieldState();
77          // WHEN
78          final Vector3D vector3D = fieldImpulseProvider.getImpulse(fieldSpacecraftState, isForward).toVector3D();
79          // THEN
80          Assertions.assertEquals(impulseProvider.getImpulse(fieldSpacecraftState.toSpacecraftState(), isForward), vector3D);
81      }
82  
83      private static FieldSpacecraftState<Binary64> buildFieldState() {
84          return new FieldSpacecraftState<>(new FieldCartesianOrbit<>(Binary64Field.getInstance(),
85                  new CartesianOrbit(new PVCoordinates(Vector3D.MINUS_J, Vector3D.MINUS_K), FramesFactory.getEME2000(), AbsoluteDate.ARBITRARY_EPOCH, 1)));
86      }
87  
88      @Test
89      void testOfImpulseProviderInit() {
90          // GIVEN
91          final Vector3D forwardImpulse = new Vector3D(1, 2, 3);
92          final TestImpulseProvider impulseProvider = new TestImpulseProvider(forwardImpulse);
93          final FieldImpulseProvider<Binary64> fieldImpulseProvider = FieldImpulseProvider.of(impulseProvider);
94          final FieldSpacecraftState<Binary64> fieldSpacecraftState = buildFieldState();
95          // WHEN
96          fieldImpulseProvider.init(fieldSpacecraftState, FieldAbsoluteDate.getArbitraryEpoch(Binary64Field.getInstance()));
97          // THEN
98          Assertions.assertTrue(impulseProvider.initialized);
99      }
100 
101     @Test
102     void testOfImpulseProviderFinish() {
103         // GIVEN
104         final Vector3D forwardImpulse = new Vector3D(1, 2, 3);
105         final TestImpulseProvider impulseProvider = new TestImpulseProvider(forwardImpulse);
106         final FieldImpulseProvider<Binary64> fieldImpulseProvider = FieldImpulseProvider.of(impulseProvider);
107         final FieldSpacecraftState<Binary64> fieldSpacecraftState = buildFieldState();
108         // WHEN
109         fieldImpulseProvider.finish(fieldSpacecraftState);
110         // THEN
111         Assertions.assertTrue(impulseProvider.finished);
112     }
113 
114     private static class TestImpulseProvider implements ImpulseProvider {
115 
116         private final Vector3D impulse;
117         boolean initialized = false;
118         boolean finished = false;
119 
120         TestImpulseProvider(final Vector3D impulse) {
121             this.impulse = impulse;
122         }
123 
124         @Override
125         public Vector3D getImpulse(SpacecraftState state, boolean isForward) {
126             return impulse;
127         }
128 
129         @Override
130         public void init(SpacecraftState initialState, AbsoluteDate targetDate) {
131             initialized = true;
132         }
133 
134         @Override
135         public void finish(SpacecraftState finalState) {
136             finished = true;
137         }
138     }
139 }
140