1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.util.Binary64;
23 import org.hipparchus.util.Binary64Field;
24 import org.hipparchus.util.FastMath;
25 import org.junit.jupiter.api.Assertions;
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.Test;
28 import org.orekit.Utils;
29 import org.orekit.attitudes.LofOffset;
30 import org.orekit.bodies.CelestialBody;
31 import org.orekit.bodies.CelestialBodyFactory;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.frames.FramesFactory;
34 import org.orekit.frames.LOFType;
35 import org.orekit.orbits.CircularOrbit;
36 import org.orekit.orbits.Orbit;
37 import org.orekit.orbits.PositionAngleType;
38 import org.orekit.propagation.FieldSpacecraftState;
39 import org.orekit.propagation.Propagator;
40 import org.orekit.propagation.SpacecraftState;
41 import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
42 import org.orekit.time.AbsoluteDate;
43 import org.orekit.time.DateComponents;
44 import org.orekit.time.TimeComponents;
45 import org.orekit.time.TimeScalesFactory;
46
47 public class SlewingPanelTest {
48
49 @Test
50 void testCorrectFixedRate() {
51
52 AbsoluteDate initialDate = propagator.getInitialState().getDate();
53 CelestialBody sun = CelestialBodyFactory.getSun();
54 Panel solarArray = new SlewingPanel(Vector3D.PLUS_J, propagator.getInitialState().getOrbit().getKeplerianMeanMotion(),
55 initialDate, new Vector3D(0.46565509814462996, 0.0, 0.884966287251619),
56 20.0, 0.0, 0.0, 0.0, 0.0);
57
58 for (double dt = 0; dt < 4000; dt += 60) {
59
60 SpacecraftState state = propagator.propagate(initialDate.shiftedBy(dt));
61
62 Vector3D sunInert = sun.getPosition(initialDate, state.getFrame());
63 Vector3D momentum = state.getPVCoordinates().getMomentum();
64 double sunElevation = FastMath.PI / 2 - Vector3D.angle(sunInert, momentum);
65 Assertions.assertEquals(15.1, FastMath.toDegrees(sunElevation), 0.1);
66
67 Vector3D n = solarArray.getNormal(state);
68 Assertions.assertEquals(0.0, n.getY(), 1.0e-10);
69
70
71 Vector3D sunSat = state.getAttitude().getRotation().applyTo(sunInert);
72 double misAlignment = Vector3D.angle(sunSat, n);
73 Assertions.assertEquals(sunElevation, misAlignment, 1.0e-3);
74
75 }
76 }
77
78 @Test
79 void testTooSlowFixedRate() {
80
81 AbsoluteDate initialDate = propagator.getInitialState().getDate();
82 CelestialBody sun = CelestialBodyFactory.getSun();
83 Panel solarArray = new SlewingPanel(Vector3D.PLUS_J,
84 0.1 * propagator.getInitialState().getOrbit().getKeplerianMeanMotion(),
85 initialDate, new Vector3D(0.46565509814462996, 0.0, 0.884966287251619),
86 20.0, 0.0, 0.0, 0.0, 0.0);
87
88 double maxDelta = 0;
89 for (double dt = 0; dt < 4000; dt += 60) {
90
91 SpacecraftState state = propagator.propagate(initialDate.shiftedBy(dt));
92
93 Vector3D sunInert = sun.getPosition(initialDate, state.getFrame());
94 Vector3D momentum = state.getPVCoordinates().getMomentum();
95 double sunElevation = FastMath.PI / 2 - Vector3D.angle(sunInert, momentum);
96 Assertions.assertEquals(15.1, FastMath.toDegrees(sunElevation), 0.1);
97
98 Vector3D n = solarArray.getNormal(state);
99 Assertions.assertEquals(0.0, n.getY(), 1.0e-10);
100
101
102 Vector3D sunSat = state.getAttitude().getRotation().applyTo(sunInert);
103 double misAlignment = Vector3D.angle(sunSat, n);
104 maxDelta = FastMath.max(maxDelta, FastMath.abs(sunElevation - misAlignment));
105
106 }
107 Assertions.assertTrue(FastMath.toDegrees(maxDelta) > 120.0);
108
109 }
110
111 @Test
112 void testNormalFixedRateDouble() {
113 AbsoluteDate initialDate = propagator.getInitialState().getDate();
114 SlewingPanel panel = new SlewingPanel(Vector3D.PLUS_J, 1.0e-3,
115 initialDate, Vector3D.PLUS_K, 20.0, 0.0, 0.0, 1.0, 0.0);
116 for (double dt = 0; dt < 4000; dt += 60) {
117 AbsoluteDate date = initialDate.shiftedBy(dt);
118 SpacecraftState state = propagator.propagate(date);
119 Vector3D normal = panel.getNormal(state);
120 Assertions.assertEquals(0, Vector3D.dotProduct(normal, Vector3D.PLUS_J), 1.0e-16);
121 }
122 }
123
124 @Test
125 void testNormalFixedRateField() {
126 AbsoluteDate initialDate = propagator.getInitialState().getDate();
127 SlewingPanel panel = new SlewingPanel(Vector3D.PLUS_J, 1.0e-3,
128 initialDate, Vector3D.PLUS_K, 20.0, 0.0, 0.0, 1.0, 0.0);
129 Field<Binary64> field = Binary64Field.getInstance();
130 for (double dt = 0; dt < 4000; dt += 60) {
131 AbsoluteDate date = initialDate.shiftedBy(dt);
132 FieldSpacecraftState<Binary64> fState = new FieldSpacecraftState<>(field, propagator.propagate(date));
133 FieldVector3D<Binary64> normal = panel.getNormal(fState);
134 Assertions.assertEquals(0, FieldVector3D.dotProduct(normal, Vector3D.PLUS_J).getReal(), 1.0e-16);
135 }
136 }
137
138 @Test
139 @BeforeEach
140 public void setUp() {
141 try {
142 Utils.setDataRoot("regular-data");
143 mu = 3.9860047e14;
144 double ae = 6.378137e6;
145 double c20 = -1.08263e-3;
146 double c30 = 2.54e-6;
147 double c40 = 1.62e-6;
148 double c50 = 2.3e-7;
149 double c60 = -5.5e-7;
150
151 AbsoluteDate date = new AbsoluteDate(new DateComponents(1970, 7, 1),
152 new TimeComponents(13, 59, 27.816),
153 TimeScalesFactory.getUTC());
154
155
156
157 Orbit circ =
158 new CircularOrbit(7178000.0, 0.5e-4, -0.5e-4, FastMath.toRadians(50.), FastMath.toRadians(280),
159 FastMath.toRadians(10.0), PositionAngleType.MEAN,
160 FramesFactory.getEME2000(), date, mu);
161 propagator =
162 new EcksteinHechlerPropagator(circ,
163 new LofOffset(circ.getFrame(), LOFType.LVLH_CCSDS),
164 ae, mu, c20, c30, c40, c50, c60);
165 } catch (OrekitException oe) {
166 Assertions.fail(oe.getLocalizedMessage());
167 }
168 }
169
170 private double mu;
171 private Propagator propagator;
172
173 }