1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.attitudes;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.complex.Complex;
22 import org.hipparchus.complex.ComplexField;
23 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
24 import org.hipparchus.geometry.euclidean.threed.Rotation;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.util.Binary64Field;
27 import org.hipparchus.util.FastMath;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.Test;
31 import org.orekit.Utils;
32 import org.orekit.bodies.CelestialBody;
33 import org.orekit.bodies.CelestialBodyFactory;
34 import org.orekit.frames.Frame;
35 import org.orekit.frames.FramesFactory;
36 import org.orekit.orbits.*;
37 import org.orekit.propagation.FieldSpacecraftState;
38 import org.orekit.propagation.SpacecraftState;
39 import org.orekit.time.AbsoluteDate;
40 import org.orekit.time.DateComponents;
41 import org.orekit.time.FieldAbsoluteDate;
42 import org.orekit.time.TimeComponents;
43 import org.orekit.time.TimeScalesFactory;
44 import org.orekit.utils.Constants;
45 import org.orekit.utils.PVCoordinates;
46 import org.orekit.utils.PVCoordinatesProvider;
47
48 class CelestialBodyPointedTest {
49
50 @Test
51 void templateTestGetAttitudeRotationSameFrame() {
52 templateTestGetAttitudeRotation(FramesFactory.getEME2000());
53 }
54
55 @Test
56 void templateTestGetAttitudeRotationDifferentFrame() {
57 templateTestGetAttitudeRotation(FramesFactory.getGCRF());
58 }
59
60 void templateTestGetAttitudeRotation(final Frame frame) {
61
62 final Frame celestialFrame = FramesFactory.getEME2000();
63 final CelestialBodyPointed celestialBodyPointed = new CelestialBodyPointed(celestialFrame,
64 CelestialBodyFactory.getSun(), Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_K);
65 final PVCoordinates pv =
66 new PVCoordinates(new Vector3D(28812595.32120171334, 5948437.45881852374, 0.0),
67 new Vector3D(0, 0, 3680.853673522056));
68 final Orbit orbit = new CartesianOrbit(pv, frame, AbsoluteDate.ARBITRARY_EPOCH, Constants.EIGEN5C_EARTH_MU);
69
70 final Rotation actualRotation = celestialBodyPointed.getAttitudeRotation(orbit, orbit.getDate(), frame);
71
72 final Rotation expectedRotation = celestialBodyPointed.getAttitude(orbit, orbit.getDate(), frame).getRotation();
73 Assertions.assertEquals(0., Rotation.distance(expectedRotation, actualRotation));
74 }
75
76 @Test
77 void testFieldGetAttitudeRotationSameFrame() {
78 templateTestFieldGetAttitudeRotation(FramesFactory.getEME2000());
79 }
80
81 @Test
82 void testFieldGetAttitudeRotationDifferentFrame() {
83 templateTestFieldGetAttitudeRotation(FramesFactory.getGCRF());
84 }
85
86 void templateTestFieldGetAttitudeRotation(final Frame frame) {
87
88 final Frame celestialFrame = FramesFactory.getEME2000();
89 final CelestialBodyPointed celestialBodyPointed = new CelestialBodyPointed(celestialFrame,
90 CelestialBodyFactory.getSun(), Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_K);
91 final PVCoordinates pv =
92 new PVCoordinates(new Vector3D(28812595.32120171334, 5948437.45881852374, 0.0),
93 new Vector3D(0, 0, 3680.853673522056));
94 final Orbit orbit = new CartesianOrbit(pv, frame, AbsoluteDate.ARBITRARY_EPOCH, Constants.EIGEN5C_EARTH_MU);
95 final FieldOrbit<Complex> fieldOrbit = new FieldCartesianOrbit<>(ComplexField.getInstance(), orbit);
96
97 final FieldRotation<Complex> actualRotation = celestialBodyPointed.getAttitudeRotation(fieldOrbit, fieldOrbit.getDate(), frame);
98
99 final FieldRotation<Complex> expectedRotation = celestialBodyPointed.getAttitude(fieldOrbit, fieldOrbit.getDate(), frame).getRotation();
100 Assertions.assertEquals(0., Rotation.distance(expectedRotation.toRotation(), actualRotation.toRotation()));
101 }
102
103 @Test
104 void testSunPointing() {
105 CelestialBody sun = CelestialBodyFactory.getSun();
106
107 final Frame frame = FramesFactory.getGCRF();
108 AbsoluteDate date = new AbsoluteDate(new DateComponents(1970, 01, 01),
109 new TimeComponents(3, 25, 45.6789),
110 TimeScalesFactory.getTAI());
111 AttitudeProvider sunPointing =
112 new CelestialBodyPointed(frame, sun, Vector3D.PLUS_K,
113 Vector3D.PLUS_I, Vector3D.PLUS_K);
114 PVCoordinates pv =
115 new PVCoordinates(new Vector3D(28812595.32120171334, 5948437.45881852374, 0.0),
116 new Vector3D(0, 0, 3680.853673522056));
117 Orbit orbit = new KeplerianOrbit(pv, frame, date, 3.986004415e14);
118 Attitude attitude = sunPointing.getAttitude(orbit, date, frame);
119
120 checkField(Binary64Field.getInstance(), sunPointing, orbit, date, frame);
121
122 Vector3D xDirection = attitude.getRotation().applyInverseTo(Vector3D.PLUS_I);
123 Vector3D zDirection = attitude.getRotation().applyInverseTo(Vector3D.PLUS_K);
124 Assertions.assertEquals(0,
125 Vector3D.dotProduct(zDirection, Vector3D.crossProduct(xDirection, Vector3D.PLUS_K)),
126 1.0e-15);
127
128
129
130 Assertions.assertEquals(FastMath.atan(1.0 / 5000.0),
131 Vector3D.angle(xDirection,
132 sun.getPosition(date, frame)),
133 1.0e-15);
134
135 double h = 0.1;
136 Attitude aMinus = sunPointing.getAttitude(orbit.shiftedBy(-h), date.shiftedBy(-h), frame);
137 Attitude a0 = sunPointing.getAttitude(orbit, date, frame);
138 Attitude aPlus = sunPointing.getAttitude(orbit.shiftedBy(h), date.shiftedBy(h), frame);
139
140
141 double errorAngleMinus = Rotation.distance(aMinus.shiftedBy(h).getRotation(),
142 a0.getRotation());
143 double evolutionAngleMinus = Rotation.distance(aMinus.getRotation(),
144 a0.getRotation());
145 Assertions.assertEquals(0.0, errorAngleMinus, 1.0e-6 * evolutionAngleMinus);
146 double errorAnglePlus = Rotation.distance(a0.getRotation(),
147 aPlus.shiftedBy(-h).getRotation());
148 double evolutionAnglePlus = Rotation.distance(a0.getRotation(),
149 aPlus.getRotation());
150 Assertions.assertEquals(0.0, errorAnglePlus, 1.0e-6 * evolutionAnglePlus);
151
152 }
153
154 private <T extends CalculusFieldElement<T>> void checkField(final Field<T> field, final AttitudeProvider provider,
155 final Orbit orbit, final AbsoluteDate date,
156 final Frame frame)
157 {
158 Attitude attitudeD = provider.getAttitude(orbit, date, frame);
159 final FieldOrbit<T> orbitF = new FieldSpacecraftState<>(field, new SpacecraftState(orbit)).getOrbit();
160 final FieldAbsoluteDate<T> dateF = new FieldAbsoluteDate<>(field, date);
161 FieldAttitude<T> attitudeF = provider.getAttitude(orbitF, dateF, frame);
162 Assertions.assertEquals(0.0, Rotation.distance(attitudeD.getRotation(), attitudeF.getRotation().toRotation()), 1.0e-15);
163 Assertions.assertEquals(0.0, Vector3D.distance(attitudeD.getSpin(), attitudeF.getSpin().toVector3D()), 1.0e-15);
164 Assertions.assertEquals(0.0, Vector3D.distance(attitudeD.getRotationAcceleration(), attitudeF.getRotationAcceleration().toVector3D()), 1.0e-15);
165 }
166
167 @BeforeEach
168 public void setUp() {
169 Utils.setDataRoot("regular-data");
170 }
171
172 }
173