1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.rugged.api;
18
19
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.EOFException;
23 import java.io.File;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.StreamCorruptedException;
27 import java.lang.reflect.Field;
28 import java.net.URISyntaxException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
32
33 import org.hipparchus.geometry.euclidean.threed.Rotation;
34 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
35 import org.hipparchus.geometry.euclidean.threed.Vector3D;
36 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
37 import org.hipparchus.util.FastMath;
38 import org.junit.jupiter.api.Assertions;
39 import org.junit.jupiter.api.Test;
40 import org.junit.jupiter.api.io.TempDir;
41 import org.orekit.attitudes.AttitudeProvider;
42 import org.orekit.attitudes.NadirPointing;
43 import org.orekit.attitudes.YawCompensation;
44 import org.orekit.bodies.BodyShape;
45 import org.orekit.bodies.CelestialBodyFactory;
46 import org.orekit.bodies.GeodeticPoint;
47 import org.orekit.bodies.OneAxisEllipsoid;
48 import org.orekit.data.DataContext;
49 import org.orekit.data.DirectoryCrawler;
50 import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
51 import org.orekit.forces.gravity.ThirdBodyAttraction;
52 import org.orekit.forces.gravity.potential.GravityFieldFactory;
53 import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
54 import org.orekit.frames.Frame;
55 import org.orekit.frames.FramesFactory;
56 import org.orekit.frames.Transform;
57 import org.orekit.orbits.CircularOrbit;
58 import org.orekit.orbits.Orbit;
59 import org.orekit.orbits.OrbitType;
60 import org.orekit.orbits.PositionAngleType;
61 import org.orekit.propagation.CartesianToleranceProvider;
62 import org.orekit.propagation.Propagator;
63 import org.orekit.propagation.SpacecraftState;
64 import org.orekit.propagation.ToleranceProvider;
65 import org.orekit.propagation.analytical.KeplerianPropagator;
66 import org.orekit.propagation.numerical.NumericalPropagator;
67 import org.orekit.rugged.errors.RuggedException;
68 import org.orekit.rugged.errors.RuggedMessages;
69 import org.orekit.rugged.linesensor.LineDatation;
70 import org.orekit.rugged.linesensor.LineSensor;
71 import org.orekit.rugged.linesensor.LinearLineDatation;
72 import org.orekit.rugged.los.LOSBuilder;
73 import org.orekit.rugged.los.TimeDependentLOS;
74 import org.orekit.rugged.raster.RandomLandscapeUpdater;
75 import org.orekit.rugged.raster.TileUpdater;
76 import org.orekit.rugged.raster.VolcanicConeElevationUpdater;
77 import org.orekit.rugged.refraction.AtmosphericRefraction;
78 import org.orekit.rugged.refraction.ConstantRefractionLayer;
79 import org.orekit.rugged.refraction.MultiLayerModel;
80 import org.orekit.rugged.utils.ExtendedEllipsoid;
81 import org.orekit.time.AbsoluteDate;
82 import org.orekit.time.TimeScale;
83 import org.orekit.time.TimeScalesFactory;
84 import org.orekit.utils.AngularDerivativesFilter;
85 import org.orekit.utils.CartesianDerivativesFilter;
86 import org.orekit.utils.Constants;
87 import org.orekit.utils.IERSConventions;
88 import org.orekit.utils.PVCoordinates;
89 import org.orekit.utils.TimeStampedAngularCoordinates;
90 import org.orekit.utils.TimeStampedPVCoordinates;
91
92 public class RuggedBuilderTest {
93
94 @TempDir
95 public File tempFolder;
96
97 @Test
98 public void testSetContextWithEphemerides()
99 throws URISyntaxException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
100
101 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
102 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
103 AbsoluteDate t0 = new AbsoluteDate("2012-01-01T00:00:00", TimeScalesFactory.getUTC());
104
105 List<TimeStampedPVCoordinates> pv = Arrays.asList(
106 createPV(t0, 0.000, -1545168.478, -7001985.361, 0.000, -1095.152224, 231.344922, -7372.851944),
107 createPV(t0, 1.000, -1546262.794, -7001750.226, -7372.851, -1093.478904, 238.925123, -7372.847995),
108 createPV(t0, 2.000, -1547355.435, -7001507.511, -14745.693, -1091.804408, 246.505033, -7372.836044),
109 createPV(t0, 3.000, -1548446.402, -7001257.216, -22118.520, -1090.128736, 254.084644, -7372.816090),
110 createPV(t0, 4.000, -1549535.693, -7000999.342, -29491.323, -1088.451892, 261.663949, -7372.788133),
111 createPV(t0, 5.000, -1550623.306, -7000733.888, -36864.094, -1086.773876, 269.242938, -7372.752175),
112 createPV(t0, 6.000, -1551709.240, -7000460.856, -44236.825, -1085.094690, 276.821604, -7372.708214),
113 createPV(t0, 7.000, -1552793.495, -7000180.245, -51609.507, -1083.414336, 284.399938, -7372.656251),
114 createPV(t0, 8.000, -1553876.068, -6999892.056, -58982.134, -1081.732817, 291.977932, -7372.596287),
115 createPV(t0, 9.000, -1554956.960, -6999596.289, -66354.697, -1080.050134, 299.555578, -7372.528320),
116 createPV(t0,10.000, -1556036.168, -6999292.945, -73727.188, -1078.366288, 307.132868, -7372.452352),
117 createPV(t0,11.000, -1557113.692, -6998982.024, -81099.599, -1076.681282, 314.709792, -7372.368382),
118 createPV(t0,12.000, -1558189.530, -6998663.526, -88471.922, -1074.995118, 322.286344, -7372.276411),
119 createPV(t0,13.000, -1559263.682, -6998337.451, -95844.150, -1073.307797, 329.862513, -7372.176439),
120 createPV(t0,14.000, -1560336.145, -6998003.801, -103216.273, -1071.619321, 337.438294, -7372.068466),
121 createPV(t0,15.000, -1561406.920, -6997662.575, -110588.284, -1069.929692, 345.013676, -7371.952492),
122 createPV(t0,16.000, -1562476.004, -6997313.774, -117960.175, -1068.238912, 352.588652, -7371.828517),
123 createPV(t0,17.000, -1563543.398, -6996957.398, -125331.938, -1066.546983, 360.163213, -7371.696542),
124 createPV(t0,18.000, -1564609.098, -6996593.447, -132703.565, -1064.853906, 367.737352, -7371.556566),
125 createPV(t0,19.000, -1565673.105, -6996221.923, -140075.049, -1063.159684, 375.311060, -7371.408591),
126 createPV(t0,20.000, -1566735.417, -6995842.825, -147446.380, -1061.464319, 382.884328, -7371.252616));
127
128 List<TimeStampedAngularCoordinates> q = Arrays.asList(
129 createQ(t0, 0.000, 0.516354347549, -0.400120145429, 0.583012133139, 0.483093065155),
130 createQ(t0, 1.000, 0.516659035405, -0.399867643627, 0.582741754688, 0.483302551263),
131 createQ(t0, 2.000, 0.516963581177, -0.399615033309, 0.582471217473, 0.483511904409),
132 createQ(t0, 3.000, 0.517267984776, -0.399362314553, 0.582200521577, 0.483721124530),
133 createQ(t0, 4.000, 0.517572246112, -0.399109487434, 0.581929667081, 0.483930211565),
134 createQ(t0, 5.000, 0.517876365096, -0.398856552030, 0.581658654071, 0.484139165451),
135 createQ(t0, 6.000, 0.518180341637, -0.398603508416, 0.581387482627, 0.484347986126),
136 createQ(t0, 7.000, 0.518484175647, -0.398350356669, 0.581116152834, 0.484556673529),
137 createQ(t0, 8.000, 0.518787867035, -0.398097096866, 0.580844664773, 0.484765227599),
138 createQ(t0, 9.000, 0.519091415713, -0.397843729083, 0.580573018530, 0.484973648272),
139 createQ(t0,10.000, 0.519394821590, -0.397590253397, 0.580301214186, 0.485181935488),
140 createQ(t0,11.000, 0.519698084578, -0.397336669885, 0.580029251825, 0.485390089185),
141 createQ(t0,12.000, 0.520001204587, -0.397082978623, 0.579757131530, 0.485598109301),
142 createQ(t0,13.000, 0.520304181527, -0.396829179688, 0.579484853385, 0.485805995775),
143 createQ(t0,14.000, 0.520607015311, -0.396575273158, 0.579212417473, 0.486013748545),
144 createQ(t0,15.000, 0.520909705847, -0.396321259108, 0.578939823877, 0.486221367550),
145 createQ(t0,16.000, 0.521212253049, -0.396067137616, 0.578667072681, 0.486428852729),
146 createQ(t0,17.000, 0.521514656825, -0.395812908759, 0.578394163969, 0.486636204020),
147 createQ(t0,18.000, 0.521816917089, -0.395558572613, 0.578121097824, 0.486843421362),
148 createQ(t0,19.000, 0.522119033749, -0.395304129256, 0.577847874330, 0.487050504694),
149 createQ(t0,20.000, 0.522421006719, -0.395049578765, 0.577574493570, 0.487257453954));
150
151 TileUpdater updater =
152 new VolcanicConeElevationUpdater(new GeodeticPoint(FastMath.toRadians(13.25667),
153 FastMath.toRadians(123.685),
154 2463.0),
155 FastMath.toRadians(30.0), 16.0,
156 FastMath.toRadians(1.0), 1201);
157
158 RuggedBuilder builder = new RuggedBuilder().
159 setDigitalElevationModel(updater, 8).
160 setAlgorithm(AlgorithmId.DUVENHAGE).
161 setTimeSpan(pv.get(0).getDate(), pv.get(pv.size() - 1).getDate(), 0.001, 5.0);
162 try {
163 builder.build();
164 Assertions.fail("an exception should have been thrown");
165 } catch (RuggedException re) {
166 Assertions.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
167 Assertions.assertEquals("RuggedBuilder.setEllipsoid()", re.getParts()[0]);
168 }
169
170 Assertions.assertTrue(builder.isOverlappingTiles());
171 builder.setOverlappingTiles(false);
172 Assertions.assertTrue(!builder.isOverlappingTiles());
173
174 builder.setEllipsoid(EllipsoidId.GRS80, BodyRotatingFrameId.ITRF);
175 try {
176 builder.build();
177 Assertions.fail("an exception should have been thrown");
178 } catch (RuggedException re) {
179 Assertions.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
180 Assertions.assertEquals("RuggedBuilder.setTrajectory()", re.getParts()[0]);
181 }
182 builder.setTrajectory(InertialFrameId.EME2000,
183 pv, 8, CartesianDerivativesFilter.USE_PV,
184 q, 8, AngularDerivativesFilter.USE_R);
185 Assertions.assertSame(FramesFactory.getEME2000(), builder.getInertialFrame());
186
187
188 Rugged rugged = builder.build();
189 Assertions.assertTrue(rugged.isLightTimeCorrected());
190 Assertions.assertTrue(rugged.isAberrationOfLightCorrected());
191 Assertions.assertTrue(builder.getLightTimeCorrection());
192 Assertions.assertTrue(builder.getAberrationOfLightCorrection());
193
194 builder.setLightTimeCorrection(false);
195 rugged = builder.build();
196 Assertions.assertFalse(rugged.isLightTimeCorrected());
197 Assertions.assertTrue(rugged.isAberrationOfLightCorrected());
198 Assertions.assertFalse(builder.getLightTimeCorrection());
199 Assertions.assertTrue(builder.getAberrationOfLightCorrection());
200
201 builder.setAberrationOfLightCorrection(false);
202 rugged = builder.build();
203 Assertions.assertFalse(rugged.isLightTimeCorrected());
204 Assertions.assertFalse(rugged.isAberrationOfLightCorrected());
205 Assertions.assertFalse(builder.getLightTimeCorrection());
206 Assertions.assertFalse(builder.getAberrationOfLightCorrection());
207
208 AtmosphericRefraction atmosphericRefraction = new MultiLayerModel(builder.getEllipsoid());
209 builder.setRefractionCorrection(atmosphericRefraction);
210 rugged = builder.build();
211
212 MultiLayerModel atmosphericRefractionFromBuilder = (MultiLayerModel) builder.getRefractionCorrection();
213 Field atmos = atmosphericRefractionFromBuilder.getClass().getDeclaredField("ellipsoid");
214 atmos.setAccessible(true);
215 ExtendedEllipsoid ellipsoidAtmos = (ExtendedEllipsoid) atmos.get(atmosphericRefractionFromBuilder);
216 Assertions.assertEquals(builder.getEllipsoid().getEquatorialRadius(), ellipsoidAtmos.getEquatorialRadius(), 1.0e-9);
217 Assertions.assertEquals(builder.getEllipsoid().getFlattening(), ellipsoidAtmos.getFlattening(), 1.0e-10);
218
219 Field layers = atmosphericRefractionFromBuilder.getClass().getDeclaredField("refractionLayers");
220 layers.setAccessible(true);
221 @SuppressWarnings("unchecked")
222 List<ConstantRefractionLayer> layersAtmos = (List<ConstantRefractionLayer>) layers.get(atmosphericRefractionFromBuilder);
223
224 Field layersExpected = atmosphericRefraction.getClass().getDeclaredField("refractionLayers");
225 layersExpected.setAccessible(true);
226 @SuppressWarnings("unchecked")
227 List<ConstantRefractionLayer> layersAtmosExpected = (List<ConstantRefractionLayer>) layersExpected.get(atmosphericRefraction);
228 Assertions.assertEquals(layersAtmosExpected.size(), layersAtmos.size());
229
230 List<ConstantRefractionLayer> copyAtmosExpected = new ArrayList<ConstantRefractionLayer>(layersAtmosExpected);
231 List<ConstantRefractionLayer> copyAtmos = new ArrayList<ConstantRefractionLayer>(layersAtmos);
232
233 Assertions.assertTrue(copyAtmosExpected.removeAll(layersAtmos) && copyAtmos.removeAll(layersAtmosExpected));
234 Assertions.assertTrue(copyAtmosExpected.isEmpty() && copyAtmos.isEmpty());
235
236
237 Assertions.assertEquals(AlgorithmId.DUVENHAGE, builder.getAlgorithm());
238 Assertions.assertEquals(6378137.0, builder.getEllipsoid().getEquatorialRadius(), 1.0e-9);
239 Assertions.assertEquals(1.0 / 298.257222101, builder.getEllipsoid().getFlattening(), 1.0e-10);
240 Assertions.assertSame(updater, builder.getTileUpdater());
241 Assertions.assertEquals(8, builder.getMaxCachedTiles());
242 Assertions.assertTrue(Double.isNaN(builder.getConstantElevation()));
243 Assertions.assertEquals(pv.get(0).getDate(), builder.getMinDate());
244 Assertions.assertEquals(pv.get(pv.size() - 1).getDate(), builder.getMaxDate());
245 Assertions.assertEquals(0.001, builder.getTStep(), 1.0e-10);
246 Assertions.assertEquals(5.0, builder.getOvershootTolerance(), 1.0e-10);
247 Assertions.assertSame(FramesFactory.getEME2000(), builder.getInertialFrame());
248 Assertions.assertSame(pv, builder.getPositionsVelocities());
249 Assertions.assertEquals(8, builder.getPVInterpolationNumber());
250 Assertions.assertEquals(CartesianDerivativesFilter.USE_PV, builder.getPVFilter());
251 Assertions.assertSame(q, builder.getQuaternions());
252 Assertions.assertEquals(8, builder.getAInterpolationNumber());
253 Assertions.assertEquals(AngularDerivativesFilter.USE_R, builder.getAFilter());
254
255 Assertions.assertTrue(builder.getLineSensors().isEmpty());
256 LineSensor lineSensor = new LineSensor("line", new LinearLineDatation(t0, 2000 / 2, 1.0 / 1.5e-3),
257 Vector3D.ZERO,
258 createLOSPerfectLine(Vector3D.PLUS_K,
259 Vector3D.PLUS_I, FastMath.toRadians(1.0), 2000));
260 builder.addLineSensor(lineSensor);
261 Assertions.assertEquals(1, builder.getLineSensors().size());
262 Assertions.assertSame(lineSensor, builder.getLineSensors().get(0));
263 builder.clearLineSensors();
264 Assertions.assertTrue(builder.getLineSensors().isEmpty());
265
266 builder.setTrajectory(InertialFrameId.GCRF,
267 pv, 8, CartesianDerivativesFilter.USE_PV,
268 q, 8, AngularDerivativesFilter.USE_R);
269 Assertions.assertSame(FramesFactory.getGCRF(), builder.getInertialFrame());
270 builder.setTrajectory(InertialFrameId.MOD,
271 pv, 8, CartesianDerivativesFilter.USE_PV,
272 q, 8, AngularDerivativesFilter.USE_R);
273 Assertions.assertSame(FramesFactory.getMOD(IERSConventions.IERS_1996), builder.getInertialFrame());
274 builder.setTrajectory(InertialFrameId.TOD,
275 pv, 8, CartesianDerivativesFilter.USE_PV,
276 q, 8, AngularDerivativesFilter.USE_R);
277 Assertions.assertSame(FramesFactory.getTOD(IERSConventions.IERS_1996, true), builder.getInertialFrame());
278 builder.setTrajectory(InertialFrameId.VEIS1950,
279 pv, 8, CartesianDerivativesFilter.USE_PV,
280 q, 8, AngularDerivativesFilter.USE_R);
281 Assertions.assertSame(FramesFactory.getVeis1950(), builder.getInertialFrame());
282
283 builder.setAlgorithm(null);
284 try {
285 builder.build();
286 Assertions.fail("an exception should have been thrown");
287 } catch (RuggedException re) {
288 Assertions.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
289 Assertions.assertEquals("RuggedBuilder.setAlgorithmID()", re.getParts()[0]);
290 }
291
292 builder.setAlgorithm(AlgorithmId.CONSTANT_ELEVATION_OVER_ELLIPSOID);
293 builder.setConstantElevation(Double.NaN);
294 try {
295 builder.build();
296 Assertions.fail("an exception should have been thrown");
297 } catch (RuggedException re) {
298 Assertions.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
299 Assertions.assertEquals("RuggedBuilder.setConstantElevation()", re.getParts()[0]);
300 }
301 builder.setConstantElevation(100.0);
302 Assertions.assertNotNull(builder.build());
303
304 builder.setAlgorithm(AlgorithmId.BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY);
305 builder.setDigitalElevationModel(null, 8);
306 try {
307 builder.build();
308 Assertions.fail("an exception should have been thrown");
309 } catch (RuggedException re) {
310 Assertions.assertEquals(RuggedMessages.UNINITIALIZED_CONTEXT, re.getSpecifier());
311 Assertions.assertEquals("RuggedBuilder.setDigitalElevationModel()", re.getParts()[0]);
312 }
313 builder.setDigitalElevationModel(updater, 8);
314 Assertions.assertNotNull(builder.build());
315
316 }
317
318 @Test
319 public void testSetContextWithPropagator()
320 throws URISyntaxException {
321
322 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
323 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
324 BodyShape earth = createEarth();
325 NormalizedSphericalHarmonicsProvider gravityField = createGravityField();
326 Orbit orbit = createOrbit(gravityField.getMu());
327 Propagator propagator = createPropagator(earth, gravityField, orbit);
328
329 TileUpdater updater =
330 new VolcanicConeElevationUpdater(new GeodeticPoint(FastMath.toRadians(13.25667),
331 FastMath.toRadians(123.685),
332 2463.0),
333 FastMath.toRadians(30.0), 16.0,
334 FastMath.toRadians(1.0), 1201);
335
336 RuggedBuilder builder = new RuggedBuilder().
337 setDigitalElevationModel(updater, 8).
338 setAlgorithm(AlgorithmId.DUVENHAGE).
339 setEllipsoid(EllipsoidId.IERS96, BodyRotatingFrameId.ITRF).
340 setTimeSpan(orbit.getDate().shiftedBy(-10.0), orbit.getDate().shiftedBy(+10.0), 0.001, 5.0).
341 setTrajectory(1.0, 8, CartesianDerivativesFilter.USE_PV, AngularDerivativesFilter.USE_R, propagator);
342
343
344 Rugged rugged = builder.build();
345 Assertions.assertTrue(rugged.isLightTimeCorrected());
346 Assertions.assertTrue(rugged.isAberrationOfLightCorrected());
347
348 builder.setLightTimeCorrection(false);
349 rugged = builder.build();
350 Assertions.assertFalse(rugged.isLightTimeCorrected());
351 Assertions.assertTrue(rugged.isAberrationOfLightCorrected());
352
353 builder.setAberrationOfLightCorrection(false);
354 rugged = builder.build();
355 Assertions.assertFalse(rugged.isLightTimeCorrected());
356 Assertions.assertFalse(rugged.isAberrationOfLightCorrected());
357 Assertions.assertEquals(orbit.getDate().shiftedBy(-10.0), rugged.getMinDate());
358 Assertions.assertEquals(orbit.getDate().shiftedBy(+10.0), rugged.getMaxDate());
359 Assertions.assertEquals(0, rugged.getLineSensors().size());
360
361 }
362
363 @Test
364 public void testOutOfTimeRange()
365 throws URISyntaxException {
366
367 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
368 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
369 AbsoluteDate t0 = new AbsoluteDate("2012-01-01T00:00:00", TimeScalesFactory.getUTC());
370
371 List<TimeStampedPVCoordinates> pv = Arrays.asList(
372 createPV(t0, 0.000, -1545168.478, -7001985.361, 0.000, -1095.152224, 231.344922, -7372.851944),
373 createPV(t0, 1.000, -1546262.794, -7001750.226, -7372.851, -1093.478904, 238.925123, -7372.847995),
374 createPV(t0, 2.000, -1547355.435, -7001507.511, -14745.693, -1091.804408, 246.505033, -7372.836044),
375 createPV(t0, 3.000, -1548446.402, -7001257.216, -22118.520, -1090.128736, 254.084644, -7372.816090),
376 createPV(t0, 4.000, -1549535.693, -7000999.342, -29491.323, -1088.451892, 261.663949, -7372.788133),
377 createPV(t0, 5.000, -1550623.306, -7000733.888, -36864.094, -1086.773876, 269.242938, -7372.752175),
378 createPV(t0, 6.000, -1551709.240, -7000460.856, -44236.825, -1085.094690, 276.821604, -7372.708214),
379 createPV(t0, 7.000, -1552793.495, -7000180.245, -51609.507, -1083.414336, 284.399938, -7372.656251),
380 createPV(t0, 8.000, -1553876.068, -6999892.056, -58982.134, -1081.732817, 291.977932, -7372.596287),
381 createPV(t0, 9.000, -1554956.960, -6999596.289, -66354.697, -1080.050134, 299.555578, -7372.528320),
382 createPV(t0,10.000, -1556036.168, -6999292.945, -73727.188, -1078.366288, 307.132868, -7372.452352));
383
384 List<TimeStampedAngularCoordinates> q = Arrays.asList(
385 createQ(t0, 4.000, 0.517572246112, -0.399109487434, 0.581929667081, 0.483930211565),
386 createQ(t0, 5.000, 0.517876365096, -0.398856552030, 0.581658654071, 0.484139165451),
387 createQ(t0, 6.000, 0.518180341637, -0.398603508416, 0.581387482627, 0.484347986126),
388 createQ(t0, 7.000, 0.518484175647, -0.398350356669, 0.581116152834, 0.484556673529),
389 createQ(t0, 8.000, 0.518787867035, -0.398097096866, 0.580844664773, 0.484765227599));
390
391 TileUpdater updater =
392 new VolcanicConeElevationUpdater(new GeodeticPoint(FastMath.toRadians(13.25667),
393 FastMath.toRadians(123.685),
394 2463.0),
395 FastMath.toRadians(30.0), 16.0,
396 FastMath.toRadians(1.0), 1201);
397
398 Assertions.assertNotNull(new RuggedBuilder().
399 setDigitalElevationModel(updater, 8).
400 setAlgorithm(AlgorithmId.DUVENHAGE).
401 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
402 setTimeSpan(t0.shiftedBy(4), t0.shiftedBy(6), 0.001, 5.0).
403 setTrajectory(InertialFrameId.EME2000,
404 pv,2, CartesianDerivativesFilter.USE_PV,
405 q, 2, AngularDerivativesFilter.USE_R).
406 build());
407 try {
408 new RuggedBuilder().
409 setDigitalElevationModel(updater, 8).
410 setAlgorithm(AlgorithmId.DUVENHAGE).
411 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
412 setTimeSpan(t0.shiftedBy(-1), t0.shiftedBy(6), 0.001, 0.0001).
413 setTrajectory(InertialFrameId.EME2000,
414 pv, 2, CartesianDerivativesFilter.USE_PV,
415 q, 2, AngularDerivativesFilter.USE_R);
416 } catch (RuggedException re) {
417 Assertions.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
418 Assertions.assertEquals(t0.shiftedBy(-1), re.getParts()[0]);
419 }
420
421 try {
422 new RuggedBuilder().
423 setDigitalElevationModel(updater, 8).
424 setAlgorithm(AlgorithmId.DUVENHAGE).
425 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
426 setTimeSpan(t0.shiftedBy(2), t0.shiftedBy(6), 0.001, 0.0001).
427 setTrajectory(InertialFrameId.EME2000,
428 pv, 2, CartesianDerivativesFilter.USE_PV,
429 q, 2, AngularDerivativesFilter.USE_R);
430 } catch (RuggedException re) {
431 Assertions.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
432 Assertions.assertEquals(t0.shiftedBy(2), re.getParts()[0]);
433 }
434
435 try {
436 new RuggedBuilder().
437 setDigitalElevationModel(updater, 8).
438 setAlgorithm(AlgorithmId.DUVENHAGE).
439 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
440 setTimeSpan(t0.shiftedBy(4), t0.shiftedBy(9), 0.001, 0.0001).
441 setTrajectory(InertialFrameId.EME2000,
442 pv, 2, CartesianDerivativesFilter.USE_PV,
443 q, 2, AngularDerivativesFilter.USE_R);
444 } catch (RuggedException re) {
445 Assertions.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
446 Assertions.assertEquals(t0.shiftedBy(9), re.getParts()[0]);
447 }
448
449 try {
450 new RuggedBuilder().
451 setDigitalElevationModel(updater, 8).
452 setAlgorithm(AlgorithmId.DUVENHAGE).
453 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
454 setTimeSpan(t0.shiftedBy(4), t0.shiftedBy(12), 0.001, 0.0001).
455 setTrajectory(InertialFrameId.EME2000,
456 pv, 2, CartesianDerivativesFilter.USE_PV,
457 q, 2, AngularDerivativesFilter.USE_R);
458 } catch (RuggedException re) {
459 Assertions.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
460 Assertions.assertEquals(t0.shiftedBy(12), re.getParts()[0]);
461 }
462
463 }
464
465 @Test
466 public void testInterpolatorDump()
467 throws URISyntaxException {
468
469 int dimension = 200;
470
471 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
472 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
473 final BodyShape earth = createEarth();
474 final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
475
476 AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
477
478
479
480
481 Vector3D position = new Vector3D(1.5, 0, -0.2);
482 TimeDependentLOS los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
483 FastMath.toRadians(50.0),
484 RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
485 Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension);
486
487
488 LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
489 int firstLine = 0;
490 int lastLine = dimension;
491 LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
492 AbsoluteDate minDate = lineSensor.getDate(firstLine);
493 AbsoluteDate maxDate = lineSensor.getDate(lastLine);
494
495 TileUpdater updater =
496 new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0x84186d1344722b8fl,
497 FastMath.toRadians(1.0), 257);
498
499 RuggedBuilder original = new RuggedBuilder().
500 setDigitalElevationModel(updater, 8).
501 setAlgorithm(AlgorithmId.DUVENHAGE).
502 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
503 setTimeSpan(minDate, maxDate, 0.001, 5.0).
504 setTrajectory(InertialFrameId.EME2000,
505 orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
506 8, CartesianDerivativesFilter.USE_PV,
507 orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
508 2, AngularDerivativesFilter.USE_R).
509 addLineSensor(lineSensor);
510
511 ByteArrayOutputStream bos = new ByteArrayOutputStream();
512 original.storeInterpolator(bos);
513 Assertions.assertTrue(bos.size() > 100000);
514 Assertions.assertTrue(bos.size() < 200000);
515
516 GeodeticPoint[] gpOriginal = original.build().directLocation("line", 100);
517
518 RuggedBuilder recovered = new RuggedBuilder().
519 setDigitalElevationModel(updater, 8).
520 setAlgorithm(AlgorithmId.DUVENHAGE).
521 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
522 setTrajectoryAndTimeSpan(new ByteArrayInputStream(bos.toByteArray())).
523 addLineSensor(lineSensor);
524 GeodeticPoint[] gpRecovered = recovered.build().directLocation("line", 100);
525
526 for (int i = 0; i < gpOriginal.length; ++i) {
527 Vector3D pOriginal = earth.transform(gpOriginal[i]);
528 Vector3D pRecovered = earth.transform(gpRecovered[i]);
529 Assertions.assertEquals(0.0, Vector3D.distance(pOriginal, pRecovered), 1.0e-15);
530 }
531
532 }
533
534 @Test
535 public void testInterpolatorCannotDump()
536 throws URISyntaxException, IOException {
537
538 int dimension = 200;
539
540 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
541 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
542 final BodyShape earth = createEarth();
543 final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
544
545 AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
546
547
548
549
550 Vector3D position = new Vector3D(1.5, 0, -0.2);
551 TimeDependentLOS los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
552 FastMath.toRadians(50.0),
553 RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
554 Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension);
555
556
557 LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
558 int firstLine = 0;
559 int lastLine = dimension;
560 LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
561 AbsoluteDate minDate = lineSensor.getDate(firstLine);
562 AbsoluteDate maxDate = lineSensor.getDate(lastLine);
563
564 RuggedBuilder original = new RuggedBuilder().
565 setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
566 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
567 setTimeSpan(minDate, maxDate, 0.001, 5.0).
568 setTrajectory(InertialFrameId.EME2000,
569 orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
570 8, CartesianDerivativesFilter.USE_PV,
571 orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
572 2, AngularDerivativesFilter.USE_R);
573
574 FileOutputStream fos = new FileOutputStream(File.createTempFile("junit", null, tempFolder));
575 fos.close();
576 try {
577 original.storeInterpolator(fos);
578 Assertions.fail("an exception should have been thrown");
579 } catch (RuggedException re) {
580 Assertions.assertEquals(IOException.class, re.getCause().getClass());
581 }
582 }
583
584 @Test
585 public void testInterpolatorDumpWrongFrame()
586 throws URISyntaxException {
587
588 int dimension = 200;
589
590 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
591 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
592 final BodyShape earth = createEarth();
593 final Orbit orbit = createOrbit(Constants.EIGEN5C_EARTH_MU);
594
595 AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
596
597
598
599
600 Vector3D position = new Vector3D(1.5, 0, -0.2);
601 TimeDependentLOS los = createLOSPerfectLine(new Rotation(Vector3D.PLUS_I,
602 FastMath.toRadians(50.0),
603 RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
604 Vector3D.PLUS_I, FastMath.toRadians(1.0), dimension);
605
606
607 LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
608 int firstLine = 0;
609 int lastLine = dimension;
610 LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
611 AbsoluteDate minDate = lineSensor.getDate(firstLine);
612 AbsoluteDate maxDate = lineSensor.getDate(lastLine);
613
614 RuggedBuilder original = new RuggedBuilder().
615 setDigitalElevationModel(null, -1).
616 setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
617 setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF).
618 setTimeSpan(minDate, maxDate, 0.001, 5.0).
619 setTrajectory(InertialFrameId.EME2000,
620 orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
621 8, CartesianDerivativesFilter.USE_PV,
622 orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25),
623 2, AngularDerivativesFilter.USE_R);
624
625 ByteArrayOutputStream bos = new ByteArrayOutputStream();
626 original.storeInterpolator(bos);
627 Assertions.assertTrue(bos.size() > 100000);
628 Assertions.assertTrue(bos.size() < 200000);
629
630 for (BodyRotatingFrameId bId : Arrays.asList(BodyRotatingFrameId.GTOD,
631 BodyRotatingFrameId.ITRF_EQUINOX)) {
632 try {
633 new RuggedBuilder().
634 setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID).
635 setEllipsoid(EllipsoidId.WGS84, bId).
636 setTrajectoryAndTimeSpan(new ByteArrayInputStream(bos.toByteArray())).build();
637 Assertions.fail("an exception should have been thrown");
638 } catch (RuggedException re) {
639 Assertions.assertEquals(RuggedMessages.FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP,
640 re.getSpecifier());
641 }
642 }
643 }
644
645 @Test
646 public void testInterpolatorNotADump()
647 throws URISyntaxException {
648
649 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
650 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
651
652
653
654
655
656
657 byte[] nonExistentClass = new byte[] {
658 -84, -19, 0, 5, 115, 114,
659 0, 16, 78, 111, 110, 69,
660 120, 105, 115, 116, 101, 110,
661 116, 67, 108, 97, 115, 115,
662 -1, -1, -1, -1, -1, -1,
663 -1, -1, 2, 0, 0, 120,
664 112
665 };
666
667
668 byte[] integerOne = new byte[] {
669 -84, -19, 0, 5, 115, 114,
670 0, 17, 106, 97, 118, 97,
671 46, 108, 97, 110, 103, 46,
672 73, 110, 116, 101, 103, 101,
673 114, 18, -30, -96, -92, -9,
674 -127,-121, 56, 2, 0, 1,
675 73, 0, 5, 118, 97, 108,
676 117, 101, 120, 114, 0, 16,
677 106, 97, 118, 97, 46, 108,
678 97, 110, 103, 46, 78, 117,
679 109, 98, 101, 114,-122, -84,
680 -107, 29, 11,-108, -32,-117,
681 2, 0, 0, 120, 112, 0,
682 0, 0, 1
683 };
684
685
686 byte[] truncatedDump = new byte[] {
687 -84, -19, 0, 5, 115, 114,
688 0, 17, 106, 97, 118, 97
689 };
690
691 byte[] notSerialization = new byte[] {
692 1, 2, 3, 4, 5, 6
693 };
694
695 for (byte[] array : Arrays.asList(nonExistentClass, integerOne, truncatedDump, notSerialization)) {
696 try {
697 new RuggedBuilder().setTrajectoryAndTimeSpan(new ByteArrayInputStream(array));
698 Assertions.fail("an exception should have been thrown");
699 } catch (RuggedException re) {
700 Assertions.assertEquals(RuggedMessages.NOT_INTERPOLATOR_DUMP_DATA,
701 re.getSpecifier());
702 if (array == nonExistentClass) {
703 Assertions.assertEquals(ClassNotFoundException.class, re.getCause().getClass());
704 } else if (array == integerOne) {
705 Assertions.assertEquals(ClassCastException.class, re.getCause().getClass());
706 } else if (array == truncatedDump) {
707 Assertions.assertEquals(EOFException.class, re.getCause().getClass());
708 } else if (array == notSerialization) {
709 Assertions.assertEquals(StreamCorruptedException.class, re.getCause().getClass());
710 }
711 }
712 }
713
714 }
715
716 protected void addSatellitePV(TimeScale gps, Frame eme2000, Frame itrf,
717 ArrayList<TimeStampedPVCoordinates> satellitePVList,
718 String absDate,
719 double px, double py, double pz, double vx, double vy, double vz) {
720 AbsoluteDate ephemerisDate = new AbsoluteDate(absDate, gps);
721 Vector3D position = new Vector3D(px, py, pz);
722 Vector3D velocity = new Vector3D(vx, vy, vz);
723 PVCoordinates pvITRF = new PVCoordinates(position, velocity);
724 Transform transform = itrf.getTransformTo(eme2000, ephemerisDate);
725 Vector3D pEME2000 = transform.transformPosition(pvITRF.getPosition());
726 Vector3D vEME2000 = transform.transformVector(pvITRF.getVelocity());
727 satellitePVList.add(new TimeStampedPVCoordinates(ephemerisDate, pEME2000, vEME2000, Vector3D.ZERO));
728 }
729
730 protected void addSatelliteQ(TimeScale gps, ArrayList<TimeStampedAngularCoordinates> satelliteQList, String absDate, double q0, double q1, double q2,
731 double q3) {
732 AbsoluteDate attitudeDate = new AbsoluteDate(absDate, gps);
733 Rotation rotation = new Rotation(q0, q1, q2, q3, true);
734 TimeStampedAngularCoordinates pair =
735 new TimeStampedAngularCoordinates(attitudeDate, rotation, Vector3D.ZERO, Vector3D.ZERO);
736 satelliteQList.add(pair);
737 }
738
739 private BodyShape createEarth() {
740 return new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
741 Constants.WGS84_EARTH_FLATTENING,
742 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
743 }
744
745 private NormalizedSphericalHarmonicsProvider createGravityField() {
746 return GravityFieldFactory.getNormalizedProvider(12, 12);
747 }
748
749 private Orbit createOrbit(double mu) {
750
751
752
753
754
755
756
757
758
759
760
761 AbsoluteDate date = new AbsoluteDate("2012-01-01T00:00:00.000", TimeScalesFactory.getUTC());
762 Frame eme2000 = FramesFactory.getEME2000();
763 return new CircularOrbit(7173352.811913891,
764 -4.029194321683225E-4, 0.0013530362644647786,
765 FastMath.toRadians(98.63218182243709),
766 FastMath.toRadians(77.55565567747836),
767 FastMath.PI, PositionAngleType.TRUE,
768 eme2000, date, mu);
769 }
770
771 private Propagator createPropagator(BodyShape earth,
772 NormalizedSphericalHarmonicsProvider gravityField,
773 Orbit orbit) {
774
775 AttitudeProvider yawCompensation = new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth));
776 SpacecraftState state = new SpacecraftState(orbit,
777 yawCompensation.getAttitude(orbit,
778 orbit.getDate(),
779 orbit.getFrame())).withMass(1180.0);
780
781
782 OrbitType type = OrbitType.CIRCULAR;
783 double[][] tolerances = ToleranceProvider.of(CartesianToleranceProvider.of(0.1)).getTolerances(orbit, type);
784 DormandPrince853Integrator integrator =
785 new DormandPrince853Integrator(1.0e-4 * orbit.getKeplerianPeriod(),
786 1.0e-1 * orbit.getKeplerianPeriod(),
787 tolerances[0], tolerances[1]);
788 integrator.setInitialStepSize(1.0e-2 * orbit.getKeplerianPeriod());
789 NumericalPropagator numericalPropagator = new NumericalPropagator(integrator);
790 numericalPropagator.addForceModel(new HolmesFeatherstoneAttractionModel(earth.getBodyFrame(), gravityField));
791 numericalPropagator.addForceModel(new ThirdBodyAttraction(CelestialBodyFactory.getSun()));
792 numericalPropagator.addForceModel(new ThirdBodyAttraction(CelestialBodyFactory.getMoon()));
793 numericalPropagator.setOrbitType(type);
794 numericalPropagator.setInitialState(state);
795 numericalPropagator.setAttitudeProvider(yawCompensation);
796 return numericalPropagator;
797
798 }
799
800 private TimeDependentLOS createLOSPerfectLine(Vector3D center, Vector3D normal, double halfAperture, int n) {
801 List<Vector3D> list = new ArrayList<Vector3D>(n);
802 for (int i = 0; i < n; ++i) {
803 double alpha = (halfAperture * (2 * i + 1 - n)) / (n - 1);
804 list.add(new Rotation(normal, alpha, RotationConvention.VECTOR_OPERATOR).applyTo(center));
805 }
806 return new LOSBuilder(list).build();
807 }
808
809 private TimeStampedPVCoordinates createPV(AbsoluteDate t0, double dt,
810 double px, double py, double pz,
811 double vx, double vy, double vz) {
812 return new TimeStampedPVCoordinates(t0.shiftedBy(dt),
813 new Vector3D(px, py, pz),
814 new Vector3D(vx, vy, vz),
815 Vector3D.ZERO);
816 }
817
818 private TimeStampedAngularCoordinates createQ(AbsoluteDate t0, double dt,
819 double q0, double q1, double q2, double q3) {
820 return new TimeStampedAngularCoordinates(t0.shiftedBy(dt),
821 new Rotation(q0, q1, q2, q3, true),
822 Vector3D.ZERO, Vector3D.ZERO);
823 }
824
825 private List<TimeStampedPVCoordinates> orbitToPV(Orbit orbit, BodyShape earth,
826 AbsoluteDate minDate, AbsoluteDate maxDate,
827 double step) {
828 Propagator propagator = new KeplerianPropagator(orbit);
829 propagator.setAttitudeProvider(new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth)));
830 propagator.propagate(minDate);
831 final List<TimeStampedPVCoordinates> list = new ArrayList<TimeStampedPVCoordinates>();
832 propagator.getMultiplexer().add(step, currentState -> list.add(new TimeStampedPVCoordinates(currentState.getDate(),
833 currentState.getPVCoordinates().getPosition(),
834 currentState.getPVCoordinates().getVelocity(),
835 Vector3D.ZERO)));
836 propagator.propagate(maxDate);
837 return list;
838 }
839
840 private List<TimeStampedAngularCoordinates> orbitToQ(Orbit orbit, BodyShape earth,
841 AbsoluteDate minDate, AbsoluteDate maxDate,
842 double step) {
843
844 Propagator propagator = new KeplerianPropagator(orbit);
845 propagator.setAttitudeProvider(new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth)));
846 propagator.propagate(minDate);
847 final List<TimeStampedAngularCoordinates> list = new ArrayList<TimeStampedAngularCoordinates>();
848 propagator.getMultiplexer().add(step, currentState -> list.add(new TimeStampedAngularCoordinates(currentState.getDate(),
849 currentState.getAttitude().getRotation(),
850 Vector3D.ZERO, Vector3D.ZERO)));
851 propagator.propagate(maxDate);
852 return list;
853 }
854
855 }
856