1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import org.hipparchus.geometry.euclidean.threed.Rotation;
20 import org.hipparchus.geometry.euclidean.threed.Vector3D;
21 import org.junit.jupiter.api.Assertions;
22 import org.junit.jupiter.api.Test;
23 import org.orekit.Utils;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.frames.Frame;
26 import org.orekit.frames.FramesFactory;
27 import org.orekit.time.AbsoluteDate;
28 import org.orekit.time.TimeScalesFactory;
29 import org.orekit.utils.Constants;
30 import org.orekit.utils.IERSConventions;
31 import org.orekit.utils.TimeStampedPVCoordinates;
32
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.List;
36 import java.util.concurrent.ExecutorService;
37 import java.util.concurrent.Executors;
38 import java.util.concurrent.Future;
39 import java.util.concurrent.TimeUnit;
40 import java.util.concurrent.atomic.AtomicReference;
41
42 public class CelestialBodyFactoryTest {
43
44 @Test
45 public void getSun() {
46 Utils.setDataRoot("regular-data");
47
48 CelestialBody sun = CelestialBodyFactory.getSun();
49 Assertions.assertNotNull(sun);
50 }
51
52 @Test
53 public void clearCache() {
54 Utils.setDataRoot("regular-data");
55
56 CelestialBody sun = CelestialBodyFactory.getSun();
57 Assertions.assertNotNull(sun);
58 CelestialBodyFactory.clearCelestialBodyCache();
59 CelestialBody sun2 = CelestialBodyFactory.getSun();
60 Assertions.assertNotNull(sun2);
61 Assertions.assertNotSame(sun, sun2);
62 }
63
64 @Test
65 public void clearLoaders() {
66 Utils.setDataRoot("regular-data");
67
68 CelestialBody sun = CelestialBodyFactory.getSun();
69 Assertions.assertNotNull(sun);
70 CelestialBodyFactory.clearCelestialBodyLoaders();
71 CelestialBody sun2 = CelestialBodyFactory.getSun();
72 Assertions.assertNotNull(sun2);
73 Assertions.assertNotSame(sun, sun2);
74 CelestialBodyFactory.clearCelestialBodyLoaders(CelestialBodyFactory.SUN);
75 CelestialBodyFactory.clearCelestialBodyCache(CelestialBodyFactory.SUN);
76 CelestialBodyFactory.addDefaultCelestialBodyLoader(JPLEphemeridesLoader.DEFAULT_DE_SUPPORTED_NAMES);
77 CelestialBody sun3 = CelestialBodyFactory.getSun();
78 Assertions.assertNotNull(sun3);
79 Assertions.assertNotSame(sun, sun3);
80 Assertions.assertNotSame(sun2, sun3);
81 }
82
83 @Test
84 void testHorizon() {
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 final TimeStampedPVCoordinates[] refPV = new TimeStampedPVCoordinates[] {
134 createPV(2000, 1, 1,
135 5.978411018921824E+08, 4.085508359611598E+08, 1.605595308103096E+08,
136 -7.892151874487445E+00, 1.017751699703826E+01, 4.554715748011852E+00),
137 createPV(2000, 1, 2,
138 5.971584965869523E+08, 4.094296790808872E+08, 1.609528639632485E+08,
139 -7.908893450088906E+00, 1.016606978596496E+01, 4.550216570971850E+00),
140 createPV(2000, 1, 3,
141 5.964744456934582E+08, 4.103075321378759E+08, 1.613458079269412E+08,
142 -7.925614558638352E+00, 1.015459888397081E+01, 4.545706740033853E+00),
143 createPV(2000, 1, 4,
144 5.957889509819047E+08, 4.111843930867567E+08, 1.617383617815004E+08,
145 -7.942315157290042E+00, 1.014310432640078E+01, 4.541186269306714E+00),
146 createPV(2000, 1, 5,
147 5.951020142261952E+08, 4.120602598852173E+08, 1.621305246082588E+08,
148 -7.958995203281466E+00, 1.013158614867071E+01, 4.536655172931710E+00),
149 createPV(2000, 1, 6,
150 5.944136372039236E+08, 4.129351304940084E+08, 1.625222954897725E+08,
151 -7.975654653933506E+00, 1.012004438626713E+01, 4.532113465082445E+00)
152 };
153
154 Utils.setDataRoot("regular-data");
155 final CelestialBody jupiter = CelestialBodyFactory.getJupiter();
156 final Frame icrf = FramesFactory.getICRF();
157 for (final TimeStampedPVCoordinates ref : refPV) {
158 TimeStampedPVCoordinates testPV = jupiter.getPVCoordinates(ref.getDate(),
159 icrf);
160 Assertions.assertEquals(0.0,
161 Vector3D.distance(ref.getPosition(), testPV.getPosition()),
162 4.0e-4);
163 Assertions.assertEquals(0.0,
164 Vector3D.distance(ref.getVelocity(), testPV.getVelocity()),
165 1.0e-11);
166 Vector3D testP = jupiter.getInertiallyOrientedFrame()
167 .getStaticTransformTo(icrf, ref.getDate())
168 .transformPosition(Vector3D.ZERO);
169 Assertions.assertEquals(
170 0.0,
171 Vector3D.distance(ref.getPosition(), testP),
172 8.0e-4);
173 testP = jupiter.getBodyOrientedFrame()
174 .getStaticTransformTo(icrf, ref.getDate())
175 .transformPosition(Vector3D.ZERO);
176 Assertions.assertEquals(
177 0.0,
178 Vector3D.distance(ref.getPosition(), testP),
179 8.0e-4);
180 }
181
182 }
183
184 private TimeStampedPVCoordinates createPV(int year, int month, int day,
185 double xKm, double yKm, double zKM,
186 double vxKmS, double vyKms, double vzKms) {
187 return new TimeStampedPVCoordinates(new AbsoluteDate(year, month, day, TimeScalesFactory.getTDB()),
188 new Vector3D( xKm * 1000, yKm * 1000, zKM * 1000),
189 new Vector3D(vxKmS * 1000, vyKms * 1000, vzKms * 1000));
190 }
191
192 @Test
193 public void multithreadTest() {
194 Utils.setDataRoot("regular-data");
195 checkMultiThread(10, 100);
196 }
197
198 private void checkMultiThread(final int threads, final int runs) {
199
200 final AtomicReference<OrekitException> caught = new AtomicReference<OrekitException>();
201 ExecutorService executorService = Executors.newFixedThreadPool(threads);
202
203 List<Future<?>> results = new ArrayList<Future<?>>();
204 for (int i = 0; i < threads; i++) {
205 Future<?> result = executorService.submit(new Runnable() {
206 public void run() {
207 try {
208 for (int run = 0; run < runs; run++) {
209 CelestialBody mars = CelestialBodyFactory.getBody(CelestialBodyFactory.MARS);
210 Assertions.assertNotNull(mars);
211 CelestialBodyFactory.clearCelestialBodyLoaders();
212 }
213 } catch (OrekitException oe) {
214 caught.set(oe);
215 }
216 }
217 });
218 results.add(result);
219 }
220
221 try {
222 executorService.shutdown();
223 executorService.awaitTermination(5, TimeUnit.SECONDS);
224 } catch (InterruptedException ie) {
225 Assertions.fail(ie.getLocalizedMessage());
226 }
227
228 for (Future<?> result : results) {
229 Assertions.assertTrue(result.isDone(),"Not all threads finished -> possible deadlock");
230 }
231
232 if (caught.get() != null) {
233 throw caught.get();
234 }
235 }
236
237 @Test
238 void testEarthMoonBarycenter() {
239 Utils.setDataRoot("regular-data/de405-ephemerides");
240 CelestialBody sun = CelestialBodyFactory.getSun();
241 CelestialBody mars = CelestialBodyFactory.getMars();
242 CelestialBody earth = CelestialBodyFactory.getEarth();
243 CelestialBody earthMoonBarycenter = CelestialBodyFactory.getEarthMoonBarycenter();
244 List<Frame> frames = Arrays.asList(FramesFactory.getEME2000(),
245 FramesFactory.getGCRF(),
246 sun.getInertiallyOrientedFrame(),
247 mars.getInertiallyOrientedFrame(),
248 earth.getInertiallyOrientedFrame());
249
250 AbsoluteDate date = new AbsoluteDate(1969, 7, 23, TimeScalesFactory.getTT());
251 final double refDistance = bodyDistance(sun, earthMoonBarycenter, date, frames.get(0));
252 for (Frame frame : frames) {
253 Assertions.assertEquals(refDistance,
254 bodyDistance(sun, earthMoonBarycenter, date, frame),
255 1.0e-14 * refDistance,frame.toString());
256 }
257 }
258
259 @Test
260 void testICRFAndGCRFAlignment() {
261 Utils.setDataRoot("regular-data");
262 final CelestialBody earthMoonBarycenter = CelestialBodyFactory.getEarthMoonBarycenter();
263 final CelestialBody solarSystemBarycenter = CelestialBodyFactory.getSolarSystemBarycenter();
264 final List<Frame> frames = Arrays.asList(earthMoonBarycenter.getInertiallyOrientedFrame(),
265 earthMoonBarycenter.getBodyOrientedFrame(),
266 solarSystemBarycenter.getInertiallyOrientedFrame(),
267 solarSystemBarycenter.getBodyOrientedFrame());
268 final Frame icrf = FramesFactory.getICRF();
269 final Frame gcrf = FramesFactory.getGCRF();
270 for (double dt = 0; dt < Constants.JULIAN_DAY; dt += 60) {
271 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
272 for (final Frame frame : frames) {
273 Assertions.assertEquals(0.0, frame.getTransformTo(icrf, date).getRotation().getAngle(), 1.0e-15);
274 Assertions.assertEquals(0.0, frame.getTransformTo(gcrf, date).getRotation().getAngle(), 1.0e-15);
275 Assertions.assertEquals(0.0, frame.getStaticTransformTo(icrf, date).getRotation().getAngle(), 1.0e-15);
276 Assertions.assertEquals(0.0, frame.getStaticTransformTo(gcrf, date).getRotation().getAngle(), 1.0e-15);
277 }
278 }
279 }
280
281 @Test
282 void testEarthInertialFrameAroundJ2000() {
283 Utils.setDataRoot("regular-data");
284 final Frame earthFrame = CelestialBodyFactory.getEarth().getInertiallyOrientedFrame();
285 final Frame base = FramesFactory.getGCRF();
286 final Rotation reference = new Rotation(Vector3D.PLUS_K, Vector3D.PLUS_J,
287 Vector3D.PLUS_K, Vector3D.PLUS_I);
288 for (double dt = -60; dt <= 60; dt += 1.0) {
289 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
290 Rotation rotation = base.getTransformTo(earthFrame, date).getRotation();
291 Assertions.assertEquals(0.0, Rotation.distance(reference, rotation), 3.0e-10);
292 }
293 }
294
295 @Test
296 void testEarthBodyOrientedFrameAroundJ2000() {
297 Utils.setDataRoot("regular-data");
298 final Frame earthFrame = CelestialBodyFactory.getEarth().getBodyOrientedFrame();
299 final Frame base = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
300 for (double dt = -60; dt <= 60; dt += 1.0) {
301 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
302 Rotation rotation = base.getTransformTo(earthFrame, date).getRotation();
303 Assertions.assertEquals(7.9426e-4, Rotation.distance(Rotation.IDENTITY, rotation), 1.0e-8);
304 }
305 }
306
307 private double bodyDistance(CelestialBody body1, CelestialBody body2, AbsoluteDate date, Frame frame)
308 {
309 Vector3D body1Position = body1.getPosition(date, frame);
310 Vector3D body2Position = body2.getPosition(date, frame);
311 Vector3D bodyPositionDifference = body1Position.subtract(body2Position);
312 return bodyPositionDifference.getNorm();
313 }
314
315 }