1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.attitudes;
18
19
20 import org.hipparchus.Field;
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.geometry.euclidean.threed.Line;
23 import org.hipparchus.geometry.euclidean.threed.Rotation;
24 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.util.Decimal64Field;
27 import org.hipparchus.util.FastMath;
28 import org.junit.After;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.orekit.Utils;
33 import org.orekit.bodies.GeodeticPoint;
34 import org.orekit.bodies.OneAxisEllipsoid;
35 import org.orekit.errors.OrekitException;
36 import org.orekit.errors.OrekitMessages;
37 import org.orekit.frames.Frame;
38 import org.orekit.frames.FramesFactory;
39 import org.orekit.frames.Transform;
40 import org.orekit.orbits.CircularOrbit;
41 import org.orekit.orbits.FieldOrbit;
42 import org.orekit.orbits.KeplerianOrbit;
43 import org.orekit.orbits.Orbit;
44 import org.orekit.orbits.PositionAngle;
45 import org.orekit.propagation.FieldSpacecraftState;
46 import org.orekit.propagation.Propagator;
47 import org.orekit.propagation.SpacecraftState;
48 import org.orekit.propagation.analytical.KeplerianPropagator;
49 import org.orekit.time.AbsoluteDate;
50 import org.orekit.time.DateComponents;
51 import org.orekit.time.FieldAbsoluteDate;
52 import org.orekit.time.TimeComponents;
53 import org.orekit.time.TimeScalesFactory;
54 import org.orekit.utils.AngularCoordinates;
55 import org.orekit.utils.Constants;
56 import org.orekit.utils.IERSConventions;
57 import org.orekit.utils.PVCoordinates;
58 import org.orekit.utils.TimeStampedFieldPVCoordinates;
59 import org.orekit.utils.TimeStampedPVCoordinates;
60
61
62 public class TargetPointingTest {
63
64
65 private AbsoluteDate date;
66
67
68 private double mu;
69
70
71 private Frame itrf;
72
73
74 private Transform eme2000ToItrf;
75
76
77
78 @Test
79 public void testConstructors() {
80
81
82
83 CircularOrbit circ =
84 new CircularOrbit(7178000.0, 0.5e-4, -0.5e-4, FastMath.toRadians(50.), FastMath.toRadians(270.),
85 FastMath.toRadians(5.300), PositionAngle.MEAN,
86 FramesFactory.getEME2000(), date, mu);
87
88
89
90
91 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
92
93
94 GeodeticPoint geoTargetITRF = new GeodeticPoint(FastMath.toRadians(43.36), FastMath.toRadians(1.26), 600.);
95 Vector3D pTargetITRF = earthShape.transform(geoTargetITRF);
96
97
98 TargetPointing geoTargetAttitudeLaw = new TargetPointing(circ.getFrame(), geoTargetITRF, earthShape);
99
100
101 TargetPointing pvTargetAttitudeLaw = new TargetPointing(circ.getFrame(), itrf, pTargetITRF);
102
103
104
105 Rotation rotPv = pvTargetAttitudeLaw.getAttitude(circ, date, circ.getFrame()).getRotation();
106
107
108 Rotation rotGeo = geoTargetAttitudeLaw.getAttitude(circ, date, circ.getFrame()).getRotation();
109
110
111 Rotation rotCompo = rotGeo.composeInverse(rotPv, RotationConvention.VECTOR_OPERATOR);
112 double angle = rotCompo.getAngle();
113 Assert.assertEquals(angle, 0.0, Utils.epsilonAngle);
114
115 }
116
117
118
119 @Test
120 public void testGeodeticConstructor() {
121
122
123
124 CircularOrbit circ =
125 new CircularOrbit(7178000.0, 0.5e-4, -0.5e-4, FastMath.toRadians(50.), FastMath.toRadians(270.),
126 FastMath.toRadians(5.300), PositionAngle.MEAN,
127 FramesFactory.getEME2000(), date, mu);
128
129
130
131
132
133 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
134
135
136 GeodeticPoint geoTargetITRF = new GeodeticPoint(FastMath.toRadians(43.36), FastMath.toRadians(1.26), 600.);
137
138
139 TargetPointing geoTargetAttitudeLaw = new TargetPointing(circ.getFrame(), geoTargetITRF, earthShape);
140
141
142 Vector3D pObservedEME2000 = geoTargetAttitudeLaw.getTargetPV(circ, date, FramesFactory.getEME2000()).getPosition();
143 GeodeticPoint geoObserved = earthShape.transform(pObservedEME2000, FramesFactory.getEME2000(), date);
144
145 Assert.assertEquals(geoObserved.getLongitude(), geoTargetITRF.getLongitude(), Utils.epsilonAngle);
146 Assert.assertEquals(geoObserved.getLatitude(), geoTargetITRF.getLatitude(), Utils.epsilonAngle);
147 Assert.assertEquals(geoObserved.getAltitude(), geoTargetITRF.getAltitude(), 1.1e-8);
148
149 }
150
151 @Test
152 public void testIssue115() {
153
154
155
156 CircularOrbit circ =
157 new CircularOrbit(7178000.0, 0.5e-4, -0.5e-4, FastMath.toRadians(50.), FastMath.toRadians(270.),
158 FastMath.toRadians(5.300), PositionAngle.MEAN,
159 FramesFactory.getEME2000(), date, mu);
160
161
162
163
164
165 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
166
167
168 GeodeticPoint geoTargetITRF = new GeodeticPoint(FastMath.toRadians(43.36), FastMath.toRadians(1.26), 600.);
169
170
171 TargetPointing geoTargetAttitudeLaw = new TargetPointing(circ.getFrame(), geoTargetITRF, earthShape);
172
173
174 Frame cirf = FramesFactory.getCIRF(IERSConventions.IERS_2010, true);
175 Attitude att1 = geoTargetAttitudeLaw.getAttitude(circ, date, cirf);
176 Attitude att2 = geoTargetAttitudeLaw.getAttitude(circ, date, itrf);
177 Attitude att3 = att2.withReferenceFrame(cirf);
178 Assert.assertEquals(0.0, Rotation.distance(att3.getRotation(), att1.getRotation()), 1.0e-15);
179
180 }
181
182 @Test
183 public void testWrongFrame() {
184 try {
185
186 new TargetPointing(itrf, FramesFactory.getEME2000(),
187 new Vector3D(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, 0, 0));
188 Assert.fail("an exception should have been thrown");
189 } catch (OrekitException oe) {
190 Assert.assertEquals(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME, oe.getSpecifier());
191 Assert.assertEquals(itrf.getName(), oe.getParts()[0]);
192 }
193 }
194
195
196
197
198 @Test
199 public void testNadirTarget() {
200
201
202 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
203
204
205 CircularOrbit circOrbit =
206 new CircularOrbit(7178000.0, 1.e-5, 0., FastMath.toRadians(50.), 0.,
207 FastMath.toRadians(90.), PositionAngle.TRUE,
208 FramesFactory.getEME2000(), date, mu);
209
210
211
212
213
214 NadirPointing nadirAttitudeLaw = new NadirPointing(circOrbit.getFrame(), earthShape);
215
216
217 Vector3D pNadirTarget = nadirAttitudeLaw.getTargetPV(circOrbit, date, itrf).getPosition();
218 GeodeticPoint geoNadirTarget = earthShape.transform(pNadirTarget, itrf, date);
219
220
221 TargetPointing targetAttitudeLaw = new TargetPointing(circOrbit.getFrame(), geoNadirTarget, earthShape);
222
223
224
225
226
227
228
229 Rotation rotTarget = targetAttitudeLaw.getAttitude(circOrbit, date, circOrbit.getFrame()).getRotation();
230
231
232 Rotation rotNadir = nadirAttitudeLaw.getAttitude(circOrbit, date, circOrbit.getFrame()).getRotation();
233
234
235 Rotation rotCompo = rotTarget.composeInverse(rotNadir, RotationConvention.VECTOR_OPERATOR);
236 double angle = rotCompo.getAngle();
237 Assert.assertEquals(angle, 0.0, Utils.epsilonAngle);
238
239
240
241
242
243
244 KeplerianPropagator extrapolator = new KeplerianPropagator(circOrbit);
245 double delta_t = 60.0;
246 AbsoluteDate extrapDate = date.shiftedBy(delta_t);
247 Orbit extrapOrbit = extrapolator.propagate(extrapDate).getOrbit();
248
249
250
251 Rotation extrapRotTarget = targetAttitudeLaw.getAttitude(extrapOrbit, extrapDate, extrapOrbit.getFrame()).getRotation();
252
253
254 Rotation extrapRotNadir = nadirAttitudeLaw.getAttitude(extrapOrbit, extrapDate, extrapOrbit.getFrame()).getRotation();
255
256
257 Rotation extrapRotCompo = extrapRotTarget.composeInverse(extrapRotNadir, RotationConvention.VECTOR_OPERATOR);
258 double extrapAngle = extrapRotCompo.getAngle();
259 Assert.assertEquals(extrapAngle, FastMath.toRadians(24.684793905118823), Utils.epsilonAngle);
260
261 }
262
263
264
265 @Test
266 public void testTargetInPointingDirection() {
267
268
269 AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 04, 07),
270 TimeComponents.H00,
271 TimeScalesFactory.getUTC());
272
273
274 Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
275
276
277 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
278
279
280 GeodeticPoint geoTarget = new GeodeticPoint(FastMath.toRadians(43.36), FastMath.toRadians(1.26), 600.);
281 TargetPointing targetAttitudeLaw = new TargetPointing(FramesFactory.getEME2000(), geoTarget, earthShape);
282
283
284
285
286 CircularOrbit circ =
287 new CircularOrbit(7178000.0, 0.5e-4, -0.5e-4, FastMath.toRadians(50.), FastMath.toRadians(270.),
288 FastMath.toRadians(5.300), PositionAngle.MEAN,
289 FramesFactory.getEME2000(), date, mu);
290
291
292 PVCoordinates pvSatEME2000 = circ.getPVCoordinates();
293
294
295
296
297 Rotation rotSatEME2000 = targetAttitudeLaw.getAttitude(circ, date, circ.getFrame()).getRotation();
298
299
300 Vector3D zSatEME2000 = rotSatEME2000.applyInverseTo(Vector3D.PLUS_K);
301
302
303 Vector3D p = eme2000ToItrf.transformPosition(pvSatEME2000.getPosition());
304 Line pointingLine = new Line(p,
305 p.add(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
306 eme2000ToItrf.transformVector(zSatEME2000)),
307 1.0e-10);
308
309
310 double distance = pointingLine.distance(earthShape.transform(geoTarget));
311
312 Assert.assertEquals(0, distance, 1.e-7);
313 }
314
315
316
317 @Test
318 public void testSlewedTarget() {
319
320
321 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 0., itrf);
322
323
324
325
326 CircularOrbit circ =
327 new CircularOrbit(42164000.0, 0.5e-8, -0.5e-8, 0., 0.,
328 FastMath.toRadians(5.300), PositionAngle.MEAN,
329 FramesFactory.getEME2000(), date, mu);
330
331
332
333 NadirPointing nadirAttitudeLaw = new NadirPointing(circ.getFrame(), earthShape);
334
335
336 Vector3D pNadirObservedEME2000 = nadirAttitudeLaw.getTargetPV(circ, date, FramesFactory.getEME2000()).getPosition();
337 Vector3D pNadirObservedITRF = eme2000ToItrf.transformPosition(pNadirObservedEME2000);
338
339 GeodeticPoint geoNadirObserved = earthShape.transform(pNadirObservedITRF, itrf, date);
340
341
342
343 TargetPointing targetLawRef = new TargetPointing(circ.getFrame(), itrf, pNadirObservedITRF);
344
345
346 Rotation rotSatRefEME2000 = targetLawRef.getAttitude(circ, date, circ.getFrame()).getRotation();
347
348
349
350 GeodeticPoint geoTarget = new GeodeticPoint(geoNadirObserved.getLatitude(),
351 geoNadirObserved.getLongitude() - FastMath.toRadians(5), geoNadirObserved.getAltitude());
352 Vector3D pTargetITRF = earthShape.transform(geoTarget);
353 TargetPointing targetLaw = new TargetPointing(circ.getFrame(), itrf, pTargetITRF);
354
355
356 Rotation rotSatEME2000 = targetLaw.getAttitude(circ, date, circ.getFrame()).getRotation();
357
358 checkField(Decimal64Field.getInstance(), targetLaw, circ, circ.getDate(), circ.getFrame());
359
360
361
362
363
364 double tanDeltaExpected = (6378136.460/(42164000.0-6378136.460))*FastMath.tan(FastMath.toRadians(5));
365 double deltaExpected = FastMath.atan(tanDeltaExpected);
366
367
368 double deltaReal = Rotation.distance(rotSatEME2000, rotSatRefEME2000);
369
370 Assert.assertEquals(deltaReal, deltaExpected, 1.e-4);
371
372 }
373
374 @Test
375 public void testSpin() {
376
377 Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
378
379
380 OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, itrf);
381
382
383 GeodeticPoint geoTarget = new GeodeticPoint(FastMath.toRadians(43.36), FastMath.toRadians(1.26), 600.);
384 AttitudeProvider law = new TargetPointing(FramesFactory.getEME2000(), geoTarget, earthShape);
385
386 KeplerianOrbit orbit =
387 new KeplerianOrbit(7178000.0, 1.e-4, FastMath.toRadians(50.),
388 FastMath.toRadians(10.), FastMath.toRadians(20.),
389 FastMath.toRadians(30.), PositionAngle.MEAN,
390 FramesFactory.getEME2000(), date, 3.986004415e14);
391
392 Propagator propagator = new KeplerianPropagator(orbit, law);
393
394 double h = 0.01;
395 SpacecraftState sMinus = propagator.propagate(date.shiftedBy(-h));
396 SpacecraftState s0 = propagator.propagate(date);
397 SpacecraftState sPlus = propagator.propagate(date.shiftedBy(h));
398
399
400 double errorAngleMinus = Rotation.distance(sMinus.shiftedBy(h).getAttitude().getRotation(),
401 s0.getAttitude().getRotation());
402 double evolutionAngleMinus = Rotation.distance(sMinus.getAttitude().getRotation(),
403 s0.getAttitude().getRotation());
404 Assert.assertEquals(0.0, errorAngleMinus, 1.0e-5 * evolutionAngleMinus);
405 double errorAnglePlus = Rotation.distance(s0.getAttitude().getRotation(),
406 sPlus.shiftedBy(-h).getAttitude().getRotation());
407 double evolutionAnglePlus = Rotation.distance(s0.getAttitude().getRotation(),
408 sPlus.getAttitude().getRotation());
409 Assert.assertEquals(0.0, errorAnglePlus, 1.0e-5 * evolutionAnglePlus);
410
411 Vector3D spin0 = s0.getAttitude().getSpin();
412 Vector3D reference = AngularCoordinates.estimateRate(sMinus.getAttitude().getRotation(),
413 sPlus.getAttitude().getRotation(),
414 2 * h);
415 Assert.assertEquals(0.0, spin0.subtract(reference).getNorm(), 1.1e-10);
416
417 }
418
419 private <T extends CalculusFieldElement<T>> void checkField(final Field<T> field, final GroundPointing provider,
420 final Orbit orbit, final AbsoluteDate date,
421 final Frame frame)
422 {
423
424 final Attitude attitudeD = provider.getAttitude(orbit, date, frame);
425 final FieldOrbit<T> orbitF = new FieldSpacecraftState<>(field, new SpacecraftState(orbit)).getOrbit();
426 final FieldAbsoluteDate<T> dateF = new FieldAbsoluteDate<>(field, date);
427 final FieldAttitude<T> attitudeF = provider.getAttitude(orbitF, dateF, frame);
428 Assert.assertEquals(0.0, Rotation.distance(attitudeD.getRotation(), attitudeF.getRotation().toRotation()), 1.0e-15);
429 Assert.assertEquals(0.0, Vector3D.distance(attitudeD.getSpin(), attitudeF.getSpin().toVector3D()), 1.0e-15);
430 Assert.assertEquals(0.0, Vector3D.distance(attitudeD.getRotationAcceleration(), attitudeF.getRotationAcceleration().toVector3D()), 1.0e-15);
431
432 final TimeStampedPVCoordinates pvD = provider.getTargetPV(orbit, date, frame);
433 final TimeStampedFieldPVCoordinates<T> pvF = provider.getTargetPV(orbitF, dateF, frame);
434 Assert.assertEquals(0.0, Vector3D.distance(pvD.getPosition(), pvF.getPosition().toVector3D()), 1.0e-15);
435 Assert.assertEquals(0.0, Vector3D.distance(pvD.getVelocity(), pvF.getVelocity().toVector3D()), 1.0e-15);
436 Assert.assertEquals(0.0, Vector3D.distance(pvD.getAcceleration(), pvF.getAcceleration().toVector3D()), 1.0e-15);
437
438 }
439
440 @Before
441 public void setUp() {
442 try {
443
444 Utils.setDataRoot("regular-data");
445
446
447 date = new AbsoluteDate(new DateComponents(2008, 04, 07),
448 TimeComponents.H00,
449 TimeScalesFactory.getUTC());
450
451
452 mu = 3.9860047e14;
453
454
455 itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
456
457
458 eme2000ToItrf = FramesFactory.getEME2000().getTransformTo(itrf, date);
459
460 } catch (OrekitException oe) {
461 Assert.fail(oe.getMessage());
462 }
463
464 }
465
466 @After
467 public void tearDown() {
468 date = null;
469 itrf = null;
470 eme2000ToItrf = null;
471 }
472
473 }
474