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.analysis.differentiation.GradientField;
22 import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
23 import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
24 import org.hipparchus.complex.ComplexField;
25 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
26 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
27 import org.hipparchus.geometry.euclidean.threed.Rotation;
28 import org.hipparchus.geometry.euclidean.threed.Vector3D;
29 import org.hipparchus.util.Binary64Field;
30 import org.junit.jupiter.api.Assertions;
31 import org.junit.jupiter.api.BeforeAll;
32 import org.junit.jupiter.api.Test;
33 import org.orekit.Utils;
34 import org.orekit.annotation.DefaultDataContext;
35 import org.orekit.frames.Frame;
36 import org.orekit.frames.FramesFactory;
37 import org.orekit.orbits.EquinoctialOrbit;
38 import org.orekit.orbits.FieldEquinoctialOrbit;
39 import org.orekit.orbits.PositionAngleType;
40 import org.orekit.time.AbsoluteDate;
41 import org.orekit.time.FieldAbsoluteDate;
42 import org.orekit.utils.Constants;
43 import org.orekit.utils.FieldPVCoordinates;
44 import org.orekit.utils.FieldPVCoordinatesProvider;
45 import org.orekit.utils.IERSConventions;
46 import org.orekit.utils.PVCoordinates;
47 import org.orekit.utils.PVCoordinatesProvider;
48 import org.orekit.utils.TimeStampedFieldPVCoordinates;
49 import org.orekit.utils.TimeStampedPVCoordinates;
50
51 class GroundPointingTest {
52
53 private static Frame INERTIAL_FRAME;
54
55 private static Frame OTHER_INERTIAL_FRAME;
56
57 private static Frame EARTH_FIXED_FRAME;
58
59 @BeforeAll
60 @DefaultDataContext
61 public static void setUp() {
62
63 Utils.setDataRoot("regular-data");
64
65 INERTIAL_FRAME = FramesFactory.getEME2000();
66 OTHER_INERTIAL_FRAME = FramesFactory.getGCRF();
67 EARTH_FIXED_FRAME = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
68
69 }
70
71 private static class TestGroundPointing extends GroundPointing {
72
73 TestGroundPointing(Frame inertialFrame, Frame bodyFrame) {
74 super(inertialFrame, bodyFrame);
75 }
76
77 @Override
78 public TimeStampedPVCoordinates getTargetPV(PVCoordinatesProvider pvProv, AbsoluteDate date, Frame frame) {
79 return new TimeStampedPVCoordinates(date, PVCoordinates.ZERO);
80 }
81
82 @Override
83 public <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T>
84 getTargetPV(FieldPVCoordinatesProvider<T> pvProv, FieldAbsoluteDate<T> date, Frame frame) {
85 return new TimeStampedFieldPVCoordinates<>(date, FieldPVCoordinates.getZero(date.getField()));
86 }
87
88 }
89
90 @Test
91 void templateTestGetRotationSameFrame() {
92 templateTestGetRotation(INERTIAL_FRAME);
93 }
94
95 @Test
96 void templateTestGetRotationDifferentFrame() {
97 templateTestGetRotation(OTHER_INERTIAL_FRAME);
98 }
99
100 private void templateTestGetRotation(final Frame frame) {
101
102 final TestGroundPointing groundPointing = new TestGroundPointing(INERTIAL_FRAME, EARTH_FIXED_FRAME);
103 final EquinoctialOrbit orbit = createPVCoordinatesProvider();
104
105 final Rotation actualRotation = groundPointing.getAttitudeRotation(orbit, orbit.getDate(), frame);
106
107 final Attitude attitude = groundPointing.getAttitude(orbit, orbit.getDate(), frame);
108 final Rotation expectedRotation = attitude.getRotation();
109 Assertions.assertEquals(0., Rotation.distance(expectedRotation, actualRotation));
110 }
111
112 @Test
113 void testGetAttitudeRotationFieldSameFrame() {
114 templateTestGetRotationField(ComplexField.getInstance(), INERTIAL_FRAME);
115 }
116
117 @Test
118 void testGetAttitudeRotationFieldDifferentFrame() {
119 templateTestGetRotationField(new UnivariateDerivative1(0., 0.).getField(), OTHER_INERTIAL_FRAME);
120 }
121
122 private <T extends CalculusFieldElement<T>> void templateTestGetRotationField(final Field<T> field,
123 final Frame frame) {
124
125 final TestGroundPointing groundPointing = new TestGroundPointing(INERTIAL_FRAME, EARTH_FIXED_FRAME);
126 final EquinoctialOrbit orbit = createPVCoordinatesProvider();
127 final FieldEquinoctialOrbit<T> fieldOrbit = convertToField(field, orbit);
128
129 final FieldRotation<T> actualRotation = groundPointing.getAttitudeRotation(fieldOrbit, fieldOrbit.getDate(), frame);
130
131 final FieldAttitude<T> attitude = groundPointing.getAttitude(fieldOrbit, fieldOrbit.getDate(), frame);
132 final FieldRotation<T> expectedRotation = attitude.getRotation();
133 Assertions.assertEquals(0., Rotation.distance(expectedRotation.toRotation(), actualRotation.toRotation()));
134 }
135
136 @Test
137 void testGetAttitudeFieldGradient() {
138 templateTestGetAttitudeField(GradientField.getField(1));
139 }
140
141 @Test
142 void testGetAttitudeFieldUnivariateDerivative2() {
143 templateTestGetAttitudeField(new UnivariateDerivative2(0., 0., 0.).getField());
144 }
145
146 private <T extends CalculusFieldElement<T>> void templateTestGetAttitudeField(final Field<T> field) {
147
148 final TestGroundPointing groundPointing = new TestGroundPointing(INERTIAL_FRAME, EARTH_FIXED_FRAME);
149 final EquinoctialOrbit orbit = createPVCoordinatesProvider();
150 final FieldEquinoctialOrbit<T> fieldOrbit = convertToField(field, orbit);
151
152 final Attitude actualAttitude = groundPointing.getAttitude(fieldOrbit, fieldOrbit.getDate(), OTHER_INERTIAL_FRAME).toAttitude();
153
154 final Attitude expectedAttitude = groundPointing.getAttitude(orbit, orbit.getDate(), OTHER_INERTIAL_FRAME);
155 Assertions.assertEquals(0., Rotation.distance(expectedAttitude.getRotation(), actualAttitude.getRotation()));
156 Assertions.assertEquals(expectedAttitude.getSpin(), actualAttitude.getSpin());
157 Assertions.assertEquals(expectedAttitude.getRotationAcceleration(), actualAttitude.getRotationAcceleration());
158 }
159
160 @Test
161 void testGetTargetPosition() {
162
163 final TestGroundPointing groundPointing = new TestGroundPointing(INERTIAL_FRAME, EARTH_FIXED_FRAME);
164 final EquinoctialOrbit orbit = createPVCoordinatesProvider();
165
166 final Vector3D actualPosition = groundPointing.getTargetPosition(orbit, orbit.getDate(), INERTIAL_FRAME);
167
168 final Vector3D expectedPosition = groundPointing.getTargetPV(orbit, orbit.getDate(), INERTIAL_FRAME).
169 getPosition();
170 Assertions.assertEquals(expectedPosition, actualPosition);
171 }
172
173 @Test
174 void testGetTargetPositionFieldBinary64() {
175 templateTestGetTargetPositionField(Binary64Field.getInstance());
176 }
177
178 @Test
179 void testGetTargetPositionFieldComplex() {
180 templateTestGetTargetPositionField(ComplexField.getInstance());
181 }
182
183 private <T extends CalculusFieldElement<T>> void templateTestGetTargetPositionField(final Field<T> field) {
184
185 final TestGroundPointing groundPointing = new TestGroundPointing(INERTIAL_FRAME, EARTH_FIXED_FRAME);
186 final EquinoctialOrbit orbit = createPVCoordinatesProvider();
187 final FieldEquinoctialOrbit<T> fieldOrbit = convertToField(field, orbit);
188
189 final FieldVector3D<T> actualPosition = groundPointing.getTargetPosition(fieldOrbit, fieldOrbit.getDate(), INERTIAL_FRAME);
190
191 final FieldVector3D<T> expectedPosition = groundPointing.getTargetPV(fieldOrbit, fieldOrbit.getDate(), INERTIAL_FRAME).
192 getPosition();
193 Assertions.assertEquals(expectedPosition, actualPosition);
194 }
195
196 private EquinoctialOrbit createPVCoordinatesProvider() {
197 final AbsoluteDate epoch = AbsoluteDate.ARBITRARY_EPOCH;
198 final double semiMajorAxis = 45000.e3;
199 final double mu = Constants.EGM96_EARTH_MU;
200 return new EquinoctialOrbit(semiMajorAxis, 0., 0., 0., 0., 0., PositionAngleType.ECCENTRIC, INERTIAL_FRAME, epoch, mu);
201 }
202
203 private <T extends CalculusFieldElement<T>> FieldEquinoctialOrbit<T> convertToField(final Field<T> field,
204 final EquinoctialOrbit orbit) {
205 final T zero = field.getZero();
206 final T fieldSemiMajorAxis = zero.add(orbit.getA());
207 final FieldAbsoluteDate<T> fieldDate = new FieldAbsoluteDate<>(field, orbit.getDate());
208 final PositionAngleType positionAngleType = PositionAngleType.MEAN;
209 final T fieldAngle = zero.add(orbit.getL(positionAngleType));
210 return new FieldEquinoctialOrbit<>(fieldSemiMajorAxis, zero, zero, zero, zero, fieldAngle,
211 positionAngleType, orbit.getFrame(), fieldDate, zero.add(orbit.getMu()));
212 }
213
214 }