1 package org.orekit.attitudes;
2
3 import org.hipparchus.geometry.euclidean.threed.Rotation;
4 import org.hipparchus.geometry.euclidean.threed.Vector3D;
5 import org.hipparchus.util.Binary64;
6 import org.hipparchus.util.Binary64Field;
7 import org.hipparchus.util.FastMath;
8 import org.junit.jupiter.api.Assertions;
9 import org.junit.jupiter.api.BeforeEach;
10 import org.junit.jupiter.api.Test;
11 import org.junit.jupiter.params.ParameterizedTest;
12 import org.junit.jupiter.params.provider.ValueSource;
13 import org.orekit.Utils;
14 import org.orekit.frames.FramesFactory;
15 import org.orekit.frames.LOFType;
16 import org.orekit.orbits.*;
17 import org.orekit.propagation.SpacecraftState;
18 import org.orekit.propagation.analytical.FieldKeplerianPropagator;
19 import org.orekit.propagation.analytical.KeplerianPropagator;
20 import org.orekit.propagation.events.DateDetector;
21 import org.orekit.time.AbsoluteDate;
22 import org.orekit.time.TimeScalesFactory;
23 import org.orekit.utils.Constants;
24 import org.orekit.utils.PVCoordinates;
25
26 class AttitudesSwitcherTest {
27
28 @Test
29 void testAddSwitchingConditionUndetectable() {
30
31 final Orbit orbit = getInitialOrbit();
32 final KeplerianPropagator propagator = new KeplerianPropagator(orbit);
33 final AttitudesSwitcher attitudesSwitcher = new AttitudesSwitcher();
34 final AttitudeProvider pastProvider = new FrameAlignedProvider(orbit.getFrame());
35 final AbsoluteDate switchingDate = orbit.getDate().shiftedBy(1e4);
36 final AttitudeProvider futureProvider = new LofOffset(orbit.getFrame(), LOFType.TNW);
37 final DateDetector detector = new DateDetector(switchingDate);
38
39 attitudesSwitcher.resetActiveProvider(pastProvider);
40 final TestSwitchHandler switchHandler = new TestSwitchHandler();
41 attitudesSwitcher.addSwitchingCondition(pastProvider, futureProvider, detector,
42 false, false, switchHandler);
43 propagator.setAttitudeProvider(attitudesSwitcher);
44 final SpacecraftState initialState = new SpacecraftState(orbit,
45 attitudesSwitcher.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
46 propagator.resetInitialState(initialState);
47 propagator.propagate(switchingDate.shiftedBy(1e2));
48 Assertions.assertEquals(0, switchHandler.count);
49 }
50
51 @ParameterizedTest
52 @ValueSource(doubles = { -1e3, 1e3 })
53 void testAddSwitchingCondition(final double timeShift) {
54
55 final Orbit orbit = getInitialOrbit();
56 final KeplerianPropagator propagator = new KeplerianPropagator(orbit);
57 final AttitudesSwitcher attitudesSwitcher = new AttitudesSwitcher();
58 final AttitudeProvider pastProvider = new FrameAlignedProvider(orbit.getFrame());
59 final AbsoluteDate switchingDate = orbit.getDate().shiftedBy(timeShift);
60 final AttitudeProvider futureProvider = new LofOffset(orbit.getFrame(), LOFType.TNW);
61 final DateDetector detector = new DateDetector(switchingDate);
62 final boolean isForward = (timeShift > 0);
63
64 if (isForward) {
65 attitudesSwitcher.resetActiveProvider(pastProvider);
66 attitudesSwitcher.addSwitchingCondition(pastProvider, futureProvider, detector,
67 true, true, null);
68 } else {
69 attitudesSwitcher.resetActiveProvider(futureProvider);
70 attitudesSwitcher.addSwitchingCondition(pastProvider, futureProvider, detector,
71 true, true, null);
72 }
73 propagator.setAttitudeProvider(attitudesSwitcher);
74 final SpacecraftState initialState = new SpacecraftState(orbit,
75 attitudesSwitcher.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
76 propagator.resetInitialState(initialState);
77
78 for (double step = 0; FastMath.abs(step) < FastMath.abs(timeShift) * 2; step += timeShift / 10) {
79 final SpacecraftState state = propagator.propagate(orbit.getDate().shiftedBy(step));
80 final Attitude attitude = state.getAttitude();
81 final AttitudeProvider expectedProvider;
82 if (FastMath.abs(step) < FastMath.abs(timeShift)) {
83 expectedProvider = isForward ? pastProvider : futureProvider;
84 } else {
85 expectedProvider = isForward ? futureProvider : pastProvider;
86 }
87 if (FastMath.abs(step - timeShift) > 1e-1) {
88 final Attitude expectedAttitude = expectedProvider.getAttitude(state.getOrbit(), state.getDate(), state.getFrame());
89 Assertions.assertEquals(0., Rotation.distance(expectedAttitude.getRotation(),
90 attitude.getRotation()));
91 Assertions.assertEquals(expectedAttitude.getSpin(), attitude.getSpin());
92 Assertions.assertEquals(expectedAttitude.getRotationAcceleration(), attitude.getRotationAcceleration());
93 }
94 }
95 }
96
97 private static Orbit getInitialOrbit() {
98 final AbsoluteDate initialDate = new AbsoluteDate(2004, 1, 1, 23, 30, 00.000, TimeScalesFactory.getUTC());
99 final Vector3D position = new Vector3D(-6142438.668, 3492467.560, -25767.25680);
100 final Vector3D velocity = new Vector3D(505.8479685, 942.7809215, 7435.922231);
101 return new KeplerianOrbit(new PVCoordinates(position, velocity),
102 FramesFactory.getEME2000(), initialDate,
103 Constants.EIGEN5C_EARTH_MU);
104 }
105
106 @ParameterizedTest
107 @ValueSource(doubles = { -1e3, 1e3 })
108 void testAddSwitchingConditionField(final double timeShift) {
109
110 final Orbit orbit = getInitialOrbit();
111 final Binary64Field field = Binary64Field.getInstance();
112 final FieldOrbit<Binary64> fieldOrbit = new FieldCartesianOrbit<>(field, orbit);
113 final FieldKeplerianPropagator<Binary64> propagator = new FieldKeplerianPropagator<>(fieldOrbit);
114 final AttitudesSwitcher attitudesSwitcher = new AttitudesSwitcher();
115 final AttitudeProvider pastProvider = new FrameAlignedProvider(orbit.getFrame());
116 final AbsoluteDate switchingDate = orbit.getDate().shiftedBy(timeShift);
117 final AttitudeProvider futureProvider = new LofOffset(orbit.getFrame(), LOFType.TNW);
118 final DateDetector detector = new DateDetector(switchingDate);
119 final boolean isForward = (timeShift > 0);
120 final TestSwitchHandler switchHandler = new TestSwitchHandler();
121
122 if (!isForward) {
123 attitudesSwitcher.resetActiveProvider(futureProvider);
124 }
125 attitudesSwitcher.addSwitchingCondition(pastProvider, futureProvider, detector,
126 true, false, switchHandler);
127 propagator.setAttitudeProvider(attitudesSwitcher);
128 propagator.propagate(fieldOrbit.getDate().shiftedBy(timeShift * 2));
129
130 Assertions.assertEquals(1, switchHandler.count);
131 Assertions.assertEquals(switchingDate, switchHandler.lastSwitchDate);
132 }
133
134 private static class TestSwitchHandler implements AttitudeSwitchHandler {
135 private int count = 0;
136 private AbsoluteDate lastSwitchDate;
137
138 @Override
139 public void switchOccurred(AttitudeProvider preceding, AttitudeProvider following, SpacecraftState state) {
140 count++;
141 lastSwitchDate = state.getDate();
142 }
143 }
144
145 @BeforeEach
146 public void setUp() {
147 Utils.setDataRoot("regular-data:potential");
148 }
149 }