1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.Future;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.atomic.AtomicReference;
32
33 import org.hipparchus.geometry.euclidean.threed.Rotation;
34 import org.hipparchus.geometry.euclidean.threed.Vector3D;
35 import org.junit.Assert;
36 import org.junit.Test;
37 import org.orekit.Utils;
38 import org.orekit.errors.OrekitException;
39 import org.orekit.frames.Frame;
40 import org.orekit.frames.FramesFactory;
41 import org.orekit.time.AbsoluteDate;
42 import org.orekit.time.TimeScalesFactory;
43 import org.orekit.utils.Constants;
44 import org.orekit.utils.IERSConventions;
45 import org.orekit.utils.TimeStampedPVCoordinates;
46
47 public class CelestialBodyFactoryTest {
48
49 @Test
50 public void getSun() {
51 Utils.setDataRoot("regular-data");
52
53 CelestialBody sun = CelestialBodyFactory.getSun();
54 Assert.assertNotNull(sun);
55 }
56
57 @Test
58 public void clearCache() {
59 Utils.setDataRoot("regular-data");
60
61 CelestialBody sun = CelestialBodyFactory.getSun();
62 Assert.assertNotNull(sun);
63 CelestialBodyFactory.clearCelestialBodyCache();
64 CelestialBody sun2 = CelestialBodyFactory.getSun();
65 Assert.assertNotNull(sun2);
66 Assert.assertNotSame(sun, sun2);
67 }
68
69 @Test
70 public void clearLoaders() {
71 Utils.setDataRoot("regular-data");
72
73 CelestialBody sun = CelestialBodyFactory.getSun();
74 Assert.assertNotNull(sun);
75 CelestialBodyFactory.clearCelestialBodyLoaders();
76 CelestialBody sun2 = CelestialBodyFactory.getSun();
77 Assert.assertNotNull(sun2);
78 Assert.assertNotSame(sun, sun2);
79 CelestialBodyFactory.clearCelestialBodyLoaders(CelestialBodyFactory.SUN);
80 CelestialBodyFactory.clearCelestialBodyCache(CelestialBodyFactory.SUN);
81 CelestialBodyFactory.addDefaultCelestialBodyLoader(JPLEphemeridesLoader.DEFAULT_DE_SUPPORTED_NAMES);
82 CelestialBody sun3 = CelestialBodyFactory.getSun();
83 Assert.assertNotNull(sun3);
84 Assert.assertNotSame(sun, sun3);
85 Assert.assertNotSame(sun2, sun3);
86 }
87
88 @Test
89 public void testHorizon() {
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
134
135
136
137
138 final TimeStampedPVCoordinates[] refPV = new TimeStampedPVCoordinates[] {
139 createPV(2000, 1, 1,
140 5.978411018921824E+08, 4.085508359611598E+08, 1.605595308103096E+08,
141 -7.892151874487445E+00, 1.017751699703826E+01, 4.554715748011852E+00),
142 createPV(2000, 1, 2,
143 5.971584965869523E+08, 4.094296790808872E+08, 1.609528639632485E+08,
144 -7.908893450088906E+00, 1.016606978596496E+01, 4.550216570971850E+00),
145 createPV(2000, 1, 3,
146 5.964744456934582E+08, 4.103075321378759E+08, 1.613458079269412E+08,
147 -7.925614558638352E+00, 1.015459888397081E+01, 4.545706740033853E+00),
148 createPV(2000, 1, 4,
149 5.957889509819047E+08, 4.111843930867567E+08, 1.617383617815004E+08,
150 -7.942315157290042E+00, 1.014310432640078E+01, 4.541186269306714E+00),
151 createPV(2000, 1, 5,
152 5.951020142261952E+08, 4.120602598852173E+08, 1.621305246082588E+08,
153 -7.958995203281466E+00, 1.013158614867071E+01, 4.536655172931710E+00),
154 createPV(2000, 1, 6,
155 5.944136372039236E+08, 4.129351304940084E+08, 1.625222954897725E+08,
156 -7.975654653933506E+00, 1.012004438626713E+01, 4.532113465082445E+00)
157 };
158
159 Utils.setDataRoot("regular-data");
160 final CelestialBody jupiter = CelestialBodyFactory.getJupiter();
161 for (final TimeStampedPVCoordinates ref : refPV) {
162 TimeStampedPVCoordinates testPV = jupiter.getPVCoordinates(ref.getDate(),
163 FramesFactory.getICRF());
164 Assert.assertEquals(0.0,
165 Vector3D.distance(ref.getPosition(), testPV.getPosition()),
166 4.0e-4);
167 Assert.assertEquals(0.0,
168 Vector3D.distance(ref.getVelocity(), testPV.getVelocity()),
169 1.0e-11);
170 }
171
172 }
173
174 private TimeStampedPVCoordinates createPV(int year, int month, int day,
175 double xKm, double yKm, double zKM,
176 double vxKmS, double vyKms, double vzKms) {
177 return new TimeStampedPVCoordinates(new AbsoluteDate(year, month, day, TimeScalesFactory.getTDB()),
178 new Vector3D( xKm * 1000, yKm * 1000, zKM * 1000),
179 new Vector3D(vxKmS * 1000, vyKms * 1000, vzKms * 1000));
180 }
181
182 @Test
183 public void testSerialization()
184 throws IOException, ClassNotFoundException {
185 Utils.setDataRoot("regular-data");
186 for (String name : new String[] {
187 CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER, CelestialBodyFactory.SUN, CelestialBodyFactory.MERCURY,
188 CelestialBodyFactory.VENUS, CelestialBodyFactory.EARTH_MOON, CelestialBodyFactory.EARTH,
189 CelestialBodyFactory.MOON, CelestialBodyFactory.MARS, CelestialBodyFactory.JUPITER,
190 CelestialBodyFactory.SATURN, CelestialBodyFactory.URANUS, CelestialBodyFactory.NEPTUNE, CelestialBodyFactory.PLUTO
191 }) {
192
193 CelestialBody original = CelestialBodyFactory.getBody(name);
194
195 ByteArrayOutputStream bosBody = new ByteArrayOutputStream();
196 ObjectOutputStream oosBody = new ObjectOutputStream(bosBody);
197 oosBody.writeObject(original);
198 Assert.assertTrue(bosBody.size() > 400);
199 Assert.assertTrue(bosBody.size() < 460);
200
201 ByteArrayInputStream bisBody = new ByteArrayInputStream(bosBody.toByteArray());
202 ObjectInputStream oisBody = new ObjectInputStream(bisBody);
203 CelestialBody deserializedBody = (CelestialBody) oisBody.readObject();
204 Assert.assertTrue(original == deserializedBody);
205
206 ByteArrayOutputStream bosInertialFrame = new ByteArrayOutputStream();
207 ObjectOutputStream oosInertialFrame = new ObjectOutputStream(bosInertialFrame);
208 oosInertialFrame.writeObject(original.getInertiallyOrientedFrame());
209 Assert.assertTrue(bosInertialFrame.size() > 400);
210 Assert.assertTrue(bosInertialFrame.size() < 460);
211
212 ByteArrayInputStream bisInertialFrame = new ByteArrayInputStream(bosInertialFrame.toByteArray());
213 ObjectInputStream oisInertialFrame = new ObjectInputStream(bisInertialFrame);
214 Frame deserializedInertialFrame = (Frame) oisInertialFrame.readObject();
215 Assert.assertTrue(original.getInertiallyOrientedFrame() == deserializedInertialFrame);
216
217 ByteArrayOutputStream bosBodyFrame = new ByteArrayOutputStream();
218 ObjectOutputStream oosBodyFrame = new ObjectOutputStream(bosBodyFrame);
219 oosBodyFrame.writeObject(original.getBodyOrientedFrame());
220 Assert.assertTrue(bosBodyFrame.size() > 400);
221 Assert.assertTrue(bosBodyFrame.size() < 460);
222
223 ByteArrayInputStream bisBodyFrame = new ByteArrayInputStream(bosBodyFrame.toByteArray());
224 ObjectInputStream oisBodyFrame = new ObjectInputStream(bisBodyFrame);
225 Frame deserializedBodyFrame = (Frame) oisBodyFrame.readObject();
226 Assert.assertTrue(original.getBodyOrientedFrame() == deserializedBodyFrame);
227
228 }
229 }
230
231 @Test
232 public void multithreadTest() {
233 Utils.setDataRoot("regular-data");
234 checkMultiThread(10, 100);
235 }
236
237 private void checkMultiThread(final int threads, final int runs) {
238
239 final AtomicReference<OrekitException> caught = new AtomicReference<OrekitException>();
240 ExecutorService executorService = Executors.newFixedThreadPool(threads);
241
242 List<Future<?>> results = new ArrayList<Future<?>>();
243 for (int i = 0; i < threads; i++) {
244 Future<?> result = executorService.submit(new Runnable() {
245 public void run() {
246 try {
247 for (int run = 0; run < runs; run++) {
248 CelestialBody mars = CelestialBodyFactory.getBody(CelestialBodyFactory.MARS);
249 Assert.assertNotNull(mars);
250 CelestialBodyFactory.clearCelestialBodyLoaders();
251 }
252 } catch (OrekitException oe) {
253 caught.set(oe);
254 }
255 }
256 });
257 results.add(result);
258 }
259
260 try {
261 executorService.shutdown();
262 executorService.awaitTermination(5, TimeUnit.SECONDS);
263 } catch (InterruptedException ie) {
264 Assert.fail(ie.getLocalizedMessage());
265 }
266
267 for (Future<?> result : results) {
268 Assert.assertTrue("Not all threads finished -> possible deadlock", result.isDone());
269 }
270
271 if (caught.get() != null) {
272 throw caught.get();
273 }
274 }
275
276 @Test
277 public void testEarthMoonBarycenter() {
278 Utils.setDataRoot("regular-data/de405-ephemerides");
279 CelestialBody sun = CelestialBodyFactory.getSun();
280 CelestialBody mars = CelestialBodyFactory.getMars();
281 CelestialBody earth = CelestialBodyFactory.getEarth();
282 CelestialBody earthMoonBarycenter = CelestialBodyFactory.getEarthMoonBarycenter();
283 List<Frame> frames = Arrays.asList(FramesFactory.getEME2000(),
284 FramesFactory.getGCRF(),
285 sun.getInertiallyOrientedFrame(),
286 mars.getInertiallyOrientedFrame(),
287 earth.getInertiallyOrientedFrame());
288
289 AbsoluteDate date = new AbsoluteDate(1969, 7, 23, TimeScalesFactory.getTT());
290 final double refDistance = bodyDistance(sun, earthMoonBarycenter, date, frames.get(0));
291 for (Frame frame : frames) {
292 Assert.assertEquals(frame.toString(), refDistance,
293 bodyDistance(sun, earthMoonBarycenter, date, frame),
294 1.0e-14 * refDistance);
295 }
296 }
297
298 @Test
299 public void testICRFAndGCRFAlignment() {
300 Utils.setDataRoot("regular-data");
301 final CelestialBody earthMoonBarycenter = CelestialBodyFactory.getEarthMoonBarycenter();
302 final CelestialBody solarSystemBarycenter = CelestialBodyFactory.getSolarSystemBarycenter();
303 final List<Frame> frames = Arrays.asList(earthMoonBarycenter.getInertiallyOrientedFrame(),
304 earthMoonBarycenter.getBodyOrientedFrame(),
305 solarSystemBarycenter.getInertiallyOrientedFrame(),
306 solarSystemBarycenter.getBodyOrientedFrame());
307 final Frame icrf = FramesFactory.getICRF();
308 final Frame gcrf = FramesFactory.getGCRF();
309 for (double dt = 0; dt < Constants.JULIAN_DAY; dt += 60) {
310 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
311 for (final Frame frame : frames) {
312 Assert.assertEquals(0.0, frame.getTransformTo(icrf, date).getRotation().getAngle(), 1.0e-15);
313 Assert.assertEquals(0.0, frame.getTransformTo(gcrf, date).getRotation().getAngle(), 1.0e-15);
314 }
315 }
316 }
317
318 @Test
319 public void testEarthInertialFrameAroundJ2000() {
320 Utils.setDataRoot("regular-data");
321 final Frame earthFrame = CelestialBodyFactory.getEarth().getInertiallyOrientedFrame();
322 final Frame base = FramesFactory.getGCRF();
323 final Rotation reference = new Rotation(Vector3D.PLUS_K, Vector3D.PLUS_J,
324 Vector3D.PLUS_K, Vector3D.PLUS_I);
325 for (double dt = -60; dt <= 60; dt += 1.0) {
326 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
327 Rotation rotation = base.getTransformTo(earthFrame, date).getRotation();
328 Assert.assertEquals(0.0, Rotation.distance(reference, rotation), 3.0e-10);
329 }
330 }
331
332 @Test
333 public void testEarthBodyOrientedFrameAroundJ2000() {
334 Utils.setDataRoot("regular-data");
335 final Frame earthFrame = CelestialBodyFactory.getEarth().getBodyOrientedFrame();
336 final Frame base = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
337 for (double dt = -60; dt <= 60; dt += 1.0) {
338 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
339 Rotation rotation = base.getTransformTo(earthFrame, date).getRotation();
340 Assert.assertEquals(7.9426e-4, Rotation.distance(Rotation.IDENTITY, rotation), 1.0e-8);
341 }
342 }
343
344 private double bodyDistance(CelestialBody body1, CelestialBody body2, AbsoluteDate date, Frame frame)
345 {
346 Vector3D body1Position = body1.getPVCoordinates(date, frame).getPosition();
347 Vector3D body2Position = body2.getPVCoordinates(date, frame).getPosition();
348 Vector3D bodyPositionDifference = body1Position.subtract(body2Position);
349 return bodyPositionDifference.getNorm();
350 }
351
352 }