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.geometry.euclidean.threed.Rotation;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.util.Binary64;
24 import org.hipparchus.util.Binary64Field;
25 import org.hipparchus.util.FastMath;
26 import org.junit.jupiter.api.AfterEach;
27 import org.junit.jupiter.api.Assertions;
28 import org.junit.jupiter.api.BeforeEach;
29 import org.junit.jupiter.api.Test;
30 import org.orekit.Utils;
31 import org.orekit.annotation.DefaultDataContext;
32 import org.orekit.bodies.OneAxisEllipsoid;
33 import org.orekit.errors.OrekitException;
34 import org.orekit.frames.Frame;
35 import org.orekit.frames.FramesFactory;
36 import org.orekit.orbits.CircularOrbit;
37 import org.orekit.orbits.FieldOrbit;
38 import org.orekit.orbits.Orbit;
39 import org.orekit.orbits.PositionAngleType;
40 import org.orekit.propagation.FieldSpacecraftState;
41 import org.orekit.propagation.Propagator;
42 import org.orekit.propagation.SpacecraftState;
43 import org.orekit.propagation.analytical.KeplerianPropagator;
44 import org.orekit.propagation.sampling.OrekitFixedStepHandler;
45 import org.orekit.time.AbsoluteDate;
46 import org.orekit.time.DateComponents;
47 import org.orekit.time.FieldAbsoluteDate;
48 import org.orekit.time.TimeComponents;
49 import org.orekit.time.TimeScalesFactory;
50 import org.orekit.utils.AngularDerivativesFilter;
51 import org.orekit.utils.FieldPVCoordinates;
52 import org.orekit.utils.IERSConventions;
53 import org.orekit.utils.PVCoordinates;
54 import org.orekit.utils.TimeStampedAngularCoordinates;
55 import org.orekit.utils.TimeStampedFieldPVCoordinates;
56 import org.orekit.utils.TimeStampedPVCoordinates;
57
58 import java.util.ArrayList;
59 import java.util.List;
60
61 public class TabulatedProviderTest {
62
63
64 private AbsoluteDate date;
65
66
67 private Frame itrf;
68
69
70 CircularOrbit circOrbit;
71
72
73 OneAxisEllipsoid earthShape;
74
75 @Test
76 @DefaultDataContext
77 void testDifferentFrames() {
78 double samplingRate = 10.0;
79 int n = 8;
80 AttitudeProvider referenceProvider = new NadirPointing(circOrbit.getFrame(), earthShape);
81 List<TimeStampedAngularCoordinates> sample = createSample(samplingRate, referenceProvider);
82 TabulatedProvider provider = new TabulatedProvider(circOrbit.getFrame(), sample, n,
83 AngularDerivativesFilter.USE_R);
84 Attitude attE = provider.getAttitude((date, frame) -> new TimeStampedPVCoordinates(date, PVCoordinates.ZERO),
85 date,
86 circOrbit.getFrame());
87 Assertions.assertEquals(circOrbit.getFrame().getName(), attE.getReferenceFrame().getName());
88 Frame gcrf = FramesFactory.getGCRF();
89 Attitude attG = provider.getAttitude((date, frame) -> new TimeStampedPVCoordinates(date, PVCoordinates.ZERO),
90 date,
91 gcrf);
92 Assertions.assertEquals(gcrf.getName(), attG.getReferenceFrame().getName());
93
94 Assertions.assertEquals(1.12e-7,
95 Rotation.distance(attE.getRotation(), attG.getRotation()), 1.0e-9);
96 Assertions.assertEquals(circOrbit.getFrame().getTransformTo(gcrf, date).getRotation().getAngle(),
97 Rotation.distance(attE.getRotation(), attG.getRotation()),
98 1.0e-14);
99
100 FieldAttitude<Binary64> attG64 =
101 provider.getAttitude((date, frame) -> new TimeStampedFieldPVCoordinates<>(date,
102 FieldPVCoordinates.getZero(Binary64Field.getInstance())),
103 new FieldAbsoluteDate<>(Binary64Field.getInstance(), date),
104 gcrf);
105 Assertions.assertEquals(gcrf.getName(), attG64.getReferenceFrame().getName());
106
107 }
108
109 @Test
110 void testWithoutRate() {
111 double samplingRate = 10.0;
112 double checkingRate = 1.0;
113 int n = 8;
114 AttitudeProvider referenceProvider = new NadirPointing(circOrbit.getFrame(), earthShape);
115 List<TimeStampedAngularCoordinates> sample = createSample(samplingRate, referenceProvider);
116 final double margin = samplingRate * n / 2;
117 final AbsoluteDate start = sample.get(0).getDate().shiftedBy(margin);
118 final AbsoluteDate end = sample.get(sample.size() - 1).getDate().shiftedBy(-margin);
119 TabulatedProvider provider = new TabulatedProvider(circOrbit.getFrame(), sample, n,
120 AngularDerivativesFilter.USE_R);
121 Assertions.assertEquals(0.0, checkError(start, end, checkingRate, referenceProvider, provider), 2.2e-14);
122 }
123
124 @Test
125 void testWithRate() {
126 double samplingRate = 10.0;
127 double checkingRate = 1.0;
128 int n = 8;
129 AttitudeProvider referenceProvider = new NadirPointing(circOrbit.getFrame(), earthShape);
130 List<TimeStampedAngularCoordinates> sample = createSample(samplingRate, referenceProvider);
131 final double margin = samplingRate * n / 2;
132 final AbsoluteDate start = sample.get(0).getDate().shiftedBy(margin);
133 final AbsoluteDate end = sample.get(sample.size() - 1).getDate().shiftedBy(-margin);
134 TabulatedProvider provider = new TabulatedProvider(circOrbit.getFrame(), sample, n,
135 AngularDerivativesFilter.USE_RR);
136 Assertions.assertEquals(0.0, checkError(start, end, checkingRate, referenceProvider, provider), 1.3e-11);
137 }
138
139 @Test
140 void testWithAcceleration() {
141 double samplingRate = 10.0;
142 double checkingRate = 1.0;
143 int n = 8;
144 AttitudeProvider referenceProvider = new NadirPointing(circOrbit.getFrame(), earthShape);
145 List<TimeStampedAngularCoordinates> sample = createSample(samplingRate, referenceProvider);
146 final double margin = samplingRate * n / 2;
147 final AbsoluteDate start = sample.get(0).getDate().shiftedBy(margin);
148 final AbsoluteDate end = sample.get(sample.size() - 1).getDate().shiftedBy(-margin);
149 TabulatedProvider provider = new TabulatedProvider(circOrbit.getFrame(), sample, n,
150 AngularDerivativesFilter.USE_RRA);
151 Assertions.assertEquals(0.0, checkError(start, end, checkingRate, referenceProvider, provider), 4.3e-9);
152 checkField(Binary64Field.getInstance(), provider, circOrbit, circOrbit.getDate(), circOrbit.getFrame());
153 }
154
155 private List<TimeStampedAngularCoordinates> createSample(double samplingRate, AttitudeProvider referenceProvider) {
156
157
158 final KeplerianPropagator referencePropagator = new KeplerianPropagator(circOrbit);
159 referencePropagator.setAttitudeProvider(referenceProvider);
160
161
162 final List<TimeStampedAngularCoordinates> sample = new ArrayList<>();
163 referencePropagator.setStepHandler(samplingRate, currentState -> sample.add(currentState.getAttitude().getOrientation()));
164 referencePropagator.propagate(circOrbit.getDate().shiftedBy(2 * circOrbit.getKeplerianPeriod()));
165
166 return sample;
167
168 }
169
170 private double checkError(final AbsoluteDate start, AbsoluteDate end, double checkingRate,
171 final AttitudeProvider referenceProvider, TabulatedProvider provider) {
172
173
174
175 Propagator interpolatingPropagator = new KeplerianPropagator(circOrbit.shiftedBy(start.durationFrom(circOrbit.getDate())));
176 interpolatingPropagator.setAttitudeProvider(provider);
177
178
179 final double[] error = new double[1];
180 interpolatingPropagator.setStepHandler(checkingRate, new OrekitFixedStepHandler() {
181
182 public void init(SpacecraftState s0, AbsoluteDate t, double step) {
183 error[0] = 0.0;
184 }
185
186 public void handleStep(SpacecraftState currentState) {
187 Attitude interpolated = currentState.getAttitude();
188 Attitude reference = referenceProvider.getAttitude(currentState.getOrbit(),
189 currentState.getDate(),
190 currentState.getFrame());
191 double localError = Rotation.distance(interpolated.getRotation(), reference.getRotation());
192 error[0] = FastMath.max(error[0], localError);
193 }
194
195 });
196
197 interpolatingPropagator.propagate(end);
198
199 return error[0];
200
201 }
202
203 private <T extends CalculusFieldElement<T>> void checkField(final Field<T> field, final AttitudeProvider provider,
204 final Orbit orbit, final AbsoluteDate date,
205 final Frame frame) {
206 Attitude attitudeD = provider.getAttitude(orbit, date, frame);
207 final FieldOrbit<T> orbitF = new FieldSpacecraftState<>(field, new SpacecraftState(orbit)).getOrbit();
208 final FieldAbsoluteDate<T> dateF = new FieldAbsoluteDate<>(field, date);
209 FieldAttitude<T> attitudeF = provider.getAttitude(orbitF, dateF, frame);
210 Assertions.assertEquals(0.0, Rotation.distance(attitudeD.getRotation(), attitudeF.getRotation().toRotation()), 1.0e-15);
211 Assertions.assertEquals(0.0, Vector3D.distance(attitudeD.getSpin(), attitudeF.getSpin().toVector3D()), 1.0e-15);
212 Assertions.assertEquals(0.0, Vector3D.distance(attitudeD.getRotationAcceleration(), attitudeF.getRotationAcceleration().toVector3D()), 1.0e-15);
213 }
214
215 @BeforeEach
216 @DefaultDataContext
217 public void setUp() {
218 try {
219 Utils.setDataRoot("regular-data");
220
221
222 date = new AbsoluteDate(new DateComponents(2008, 4, 7),
223 TimeComponents.H00,
224 TimeScalesFactory.getUTC());
225
226
227 final double mu = 3.9860047e14;
228
229
230 itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
231
232
233 circOrbit =
234 new CircularOrbit(7178000.0, 0.5e-4, -0.5e-4, FastMath.toRadians(50.), FastMath.toRadians(270.),
235 FastMath.toRadians(5.300), PositionAngleType.MEAN,
236 FramesFactory.getEME2000(), date, mu);
237
238
239 earthShape =
240 new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
241
242 } catch (OrekitException oe) {
243 Assertions.fail(oe.getMessage());
244 }
245
246 }
247
248 @AfterEach
249 public void tearDown() {
250 date = null;
251 itrf = null;
252 circOrbit = null;
253 earthShape = null;
254 }
255
256 }
257