1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.general;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.FastMath;
21 import org.junit.jupiter.api.Assertions;
22 import org.junit.jupiter.api.BeforeEach;
23 import org.junit.jupiter.api.Test;
24 import org.orekit.Utils;
25 import org.orekit.attitudes.FrameAlignedProvider;
26 import org.orekit.bodies.CelestialBody;
27 import org.orekit.bodies.CelestialBodyFactory;
28 import org.orekit.bodies.GeodeticPoint;
29 import org.orekit.bodies.OneAxisEllipsoid;
30 import org.orekit.data.DataSource;
31 import org.orekit.errors.OrekitException;
32 import org.orekit.files.ccsds.definitions.BodyFacade;
33 import org.orekit.files.ccsds.definitions.FrameFacade;
34 import org.orekit.files.ccsds.definitions.TimeSystem;
35 import org.orekit.files.ccsds.ndm.ParserBuilder;
36 import org.orekit.files.ccsds.ndm.WriterBuilder;
37 import org.orekit.files.ccsds.ndm.odm.oem.EphemerisOemWriter;
38 import org.orekit.files.ccsds.ndm.odm.oem.OemMetadata;
39 import org.orekit.files.ccsds.ndm.odm.oem.OemParser;
40 import org.orekit.files.ccsds.ndm.odm.oem.OemSegment;
41 import org.orekit.files.ccsds.utils.FileFormat;
42 import org.orekit.files.general.EphemerisFile.EphemerisSegment;
43 import org.orekit.files.general.OrekitEphemerisFile.OrekitSatelliteEphemeris;
44 import org.orekit.frames.Frame;
45 import org.orekit.frames.FramesFactory;
46 import org.orekit.frames.TopocentricFrame;
47 import org.orekit.orbits.CartesianOrbit;
48 import org.orekit.orbits.KeplerianOrbit;
49 import org.orekit.orbits.PositionAngleType;
50 import org.orekit.propagation.Propagator;
51 import org.orekit.propagation.SpacecraftState;
52 import org.orekit.propagation.SpacecraftStateInterpolator;
53 import org.orekit.propagation.analytical.Ephemeris;
54 import org.orekit.propagation.analytical.KeplerianPropagator;
55 import org.orekit.propagation.events.ElevationDetector;
56 import org.orekit.propagation.events.EventsLogger;
57 import org.orekit.propagation.events.EventsLogger.LoggedEvent;
58 import org.orekit.time.AbsoluteDate;
59 import org.orekit.time.TimeInterpolator;
60 import org.orekit.utils.CartesianDerivativesFilter;
61 import org.orekit.utils.Constants;
62 import org.orekit.utils.IERSConventions;
63 import org.orekit.utils.TimeStampedPVCoordinates;
64
65 import java.io.IOException;
66 import java.nio.file.Files;
67 import java.nio.file.Paths;
68 import java.util.ArrayList;
69 import java.util.List;
70
71 public class OrekitEphemerisFileTest {
72
73 @BeforeEach
74 public void setUp() throws Exception {
75 Utils.setDataRoot("regular-data");
76 }
77
78 @Test
79 public void testOrekitEphemerisFile() {
80 Assertions.assertNotNull(new OrekitEphemerisFile());
81 }
82
83 @Test
84 public void testGetSatellites() {
85 final String id1 = "ID1";
86 final String id2 = "ID2";
87 OrekitEphemerisFile file = new OrekitEphemerisFile();
88 OrekitSatelliteEphemeris ephem1 = file.addSatellite(id1);
89 Assertions.assertNotNull(ephem1);
90 OrekitSatelliteEphemeris ephem2 = file.addSatellite(id2);
91 Assertions.assertNotNull(ephem2);
92 }
93
94 @Test
95 public void testWritingToOEMKvn() throws IOException {
96 doTestWritingToOEM(FileFormat.KVN);
97 }
98
99 @Test
100 public void testWritingToOEMXml() throws IOException {
101 doTestWritingToOEM(FileFormat.XML);
102 }
103
104 private void doTestWritingToOEM(final FileFormat fileFormat) throws IOException {
105 final double muTolerance = 1e-12;
106
107 final double positionTolerance = 1.;
108
109 final double velocityTolerance = 1e-2;
110 final String satId = "SATELLITE1";
111 final double sma = 10000000;
112 final double inc = Math.toRadians(45.0);
113 final double ecc = 0.001;
114 final double raan = 0.0;
115 final double pa = 0.0;
116 final double ta = 0.0;
117 final AbsoluteDate date = new AbsoluteDate();
118 final Frame frame = FramesFactory.getGCRF();
119 final CelestialBody body = CelestialBodyFactory.getEarth();
120 final double mu = body.getGM();
121 KeplerianOrbit initialOrbit = new KeplerianOrbit(sma, ecc, inc, pa, raan, ta, PositionAngleType.TRUE, frame, date,
122 mu);
123 KeplerianPropagator propagator = new KeplerianPropagator(initialOrbit);
124
125 final double propagationDurationSeconds = 86400.0;
126 final double stepSizeSeconds = 60.0;
127 List<SpacecraftState> states = new ArrayList<SpacecraftState>();
128
129 for (double dt = 0.0; dt < propagationDurationSeconds; dt += stepSizeSeconds) {
130 states.add(propagator.propagate(date.shiftedBy(dt)));
131 }
132
133 OrekitEphemerisFile ephemerisFile = new OrekitEphemerisFile();
134 OrekitSatelliteEphemeris satellite = ephemerisFile.addSatellite(satId);
135 satellite.addNewSegment(states);
136 Assertions.assertEquals(satId, satellite.getId());
137 Assertions.assertEquals(body.getGM(), satellite.getMu(), muTolerance);
138 Assertions.assertEquals(0.0, states.get(0).getDate().durationFrom(satellite.getStart()), 1.0e-15);
139 Assertions.assertEquals(0.0, states.get(states.size() - 1).getDate().durationFrom(satellite.getStop()), 1.0e-15);
140 Assertions.assertEquals(CartesianDerivativesFilter.USE_PV,
141 satellite.getSegments().get(0).getAvailableDerivatives());
142 Assertions.assertEquals("GCRF",
143 satellite.getSegments().get(0).getFrame().getName());
144 Assertions.assertEquals(body.getGM(),
145 satellite.getSegments().get(0).getMu(), muTolerance);
146
147 String tempOem = Files.createTempFile("OrekitEphemerisFileTest", ".oem").toString();
148 OemMetadata template = new OemMetadata(2);
149 template.setTimeSystem(TimeSystem.UTC);
150 template.setObjectID(satId);
151 template.setObjectName(satId);
152 template.setCenter(new BodyFacade("EARTH", CelestialBodyFactory.getCelestialBodies().getEarth()));
153 template.setReferenceFrame(FrameFacade.map(FramesFactory.getEME2000()));
154 EphemerisOemWriter writer = new EphemerisOemWriter(new WriterBuilder().buildOemWriter(),
155 null, template, fileFormat, "dummy",
156 Constants.JULIAN_DAY, 60);
157 writer.write(tempOem, ephemerisFile);
158
159 OemParser parser = new ParserBuilder().withMu(body.getGM()).withDefaultInterpolationDegree(2).buildOemParser();
160 EphemerisFile<TimeStampedPVCoordinates, OemSegment> ephemerisFrom = parser.parse(new DataSource(tempOem));
161 Files.delete(Paths.get(tempOem));
162
163 EphemerisSegment<TimeStampedPVCoordinates> segment = ephemerisFrom.getSatellites().get(satId).getSegments().get(0);
164 Assertions.assertEquals(states.get(0).getDate(), segment.getStart());
165 Assertions.assertEquals(states.get(states.size() - 1).getDate(), segment.getStop());
166 Assertions.assertEquals(states.size(), segment.getCoordinates().size());
167 Assertions.assertEquals(frame, segment.getFrame());
168 Assertions.assertEquals(body.getGM(), segment.getMu(), muTolerance);
169 Assertions.assertEquals(CartesianDerivativesFilter.USE_PV, segment.getAvailableDerivatives());
170 Assertions.assertEquals("GCRF", segment.getFrame().getName());
171 for (int i = 0; i < states.size(); i++) {
172 TimeStampedPVCoordinates expected = states.get(i).getPVCoordinates();
173 TimeStampedPVCoordinates actual = segment.getCoordinates().get(i);
174 Assertions.assertEquals(expected.getDate(), actual.getDate());
175 Assertions.assertEquals(0.0, Vector3D.distance(expected.getPosition(), actual.getPosition()), positionTolerance);
176 Assertions.assertEquals(0.0, Vector3D.distance(expected.getVelocity(), actual.getVelocity()), velocityTolerance);
177 }
178
179
180 final OneAxisEllipsoid parentShape = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
181 Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true));
182 final double latitude = 0.0;
183 final double longitude = 0.0;
184 final double altitude = 0.0;
185 final GeodeticPoint point = new GeodeticPoint(latitude, longitude, altitude);
186 final TopocentricFrame topo = new TopocentricFrame(parentShape, point, "testPoint1");
187 final ElevationDetector elevationDetector = new ElevationDetector(topo);
188 final EphemerisSegmentPropagator<TimeStampedPVCoordinates> ephemerisSegmentPropagator =
189 new EphemerisSegmentPropagator<>(segment, new FrameAlignedProvider(segment.getInertialFrame()));
190 final EventsLogger lookupLogger = new EventsLogger();
191 ephemerisSegmentPropagator.addEventDetector(lookupLogger.monitorDetector(elevationDetector));
192
193 final EventsLogger referenceLogger = new EventsLogger();
194 propagator.clearEventsDetectors();
195 propagator.addEventDetector(referenceLogger.monitorDetector(elevationDetector));
196
197 propagator.propagate(segment.getStart(), segment.getStop());
198 ephemerisSegmentPropagator.propagate(segment.getStart(), segment.getStop());
199
200 final double dateEpsilon = 4.2e-5;
201 Assertions.assertTrue(referenceLogger.getLoggedEvents().size() > 0);
202 Assertions.assertEquals(referenceLogger.getLoggedEvents().size(), lookupLogger.getLoggedEvents().size());
203 for (int i = 0; i < referenceLogger.getLoggedEvents().size(); i++) {
204 LoggedEvent reference = referenceLogger.getLoggedEvents().get(i);
205 LoggedEvent actual = lookupLogger.getLoggedEvents().get(i);
206 Assertions.assertEquals(0.0,
207 FastMath.abs(reference.getState().getDate().durationFrom(actual.getState().getDate())),
208 dateEpsilon);
209 }
210
211 final Propagator embeddedPropagator = segment.getPropagator(new FrameAlignedProvider(segment.getInertialFrame()));
212 final EventsLogger embeddedPropLogger = new EventsLogger();
213 embeddedPropagator.addEventDetector(embeddedPropLogger.monitorDetector(elevationDetector));
214 embeddedPropagator.propagate(segment.getStart(), segment.getStop());
215 Assertions.assertEquals(referenceLogger.getLoggedEvents().size(), embeddedPropLogger.getLoggedEvents().size());
216 for (int i = 0; i < referenceLogger.getLoggedEvents().size(); i++) {
217 LoggedEvent reference = referenceLogger.getLoggedEvents().get(i);
218 LoggedEvent actual = embeddedPropLogger.getLoggedEvents().get(i);
219 Assertions.assertEquals(0.0,
220 FastMath.abs(reference.getState().getDate().durationFrom(actual.getState().getDate())),
221 dateEpsilon);
222
223 }
224
225 final List<SpacecraftState> readInStates = new ArrayList<SpacecraftState>();
226 segment.getCoordinates().forEach(c -> {
227 try {
228 readInStates.add(new SpacecraftState(new CartesianOrbit(c, frame, mu)));
229 } catch (IllegalArgumentException | OrekitException e) {
230 Assertions.fail(e.getLocalizedMessage());
231 }
232 });
233
234
235 final int interpolationPoints = 5;
236 final TimeInterpolator<SpacecraftState> interpolator =
237 new SpacecraftStateInterpolator(interpolationPoints, frame, frame);
238
239 Ephemeris directEphemProp = new Ephemeris(readInStates, interpolator);
240 final EventsLogger directEphemPropLogger = new EventsLogger();
241 directEphemProp.addEventDetector(directEphemPropLogger.monitorDetector(elevationDetector));
242 directEphemProp.propagate(segment.getStart(), segment.getStop());
243 Assertions.assertEquals(referenceLogger.getLoggedEvents().size(), directEphemPropLogger.getLoggedEvents().size());
244 for (int i = 0; i < referenceLogger.getLoggedEvents().size(); i++) {
245 LoggedEvent reference = referenceLogger.getLoggedEvents().get(i);
246 LoggedEvent actual = directEphemPropLogger.getLoggedEvents().get(i);
247 Assertions.assertEquals(0.0,
248 FastMath.abs(reference.getState().getDate().durationFrom(actual.getState().getDate())),
249 dateEpsilon);
250 }
251
252 }
253
254 }