1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm.odm.ocm;
18
19 import java.io.IOException;
20 import java.util.Collections;
21
22 import org.hipparchus.exception.LocalizedCoreFormats;
23 import org.orekit.bodies.OneAxisEllipsoid;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.files.ccsds.definitions.FrameFacade;
27 import org.orekit.files.ccsds.ndm.odm.OdmHeader;
28 import org.orekit.files.ccsds.section.XmlStructureKey;
29 import org.orekit.files.ccsds.utils.FileFormat;
30 import org.orekit.files.ccsds.utils.generation.Generator;
31 import org.orekit.frames.Frame;
32 import org.orekit.propagation.Propagator;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.propagation.sampling.OrekitFixedStepHandler;
35 import org.orekit.time.AbsoluteDate;
36 import org.orekit.utils.TimeStampedPVCoordinates;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public class StreamingOcmWriter implements AutoCloseable {
92
93
94 private final Generator generator;
95
96
97 private final OcmWriter writer;
98
99
100 private TrajectoryStateHistoryWriter trajectoryWriter;
101
102
103 private final OdmHeader header;
104
105
106 private final OcmMetadata metadata;
107
108
109 private final TrajectoryStateHistoryMetadata trajectoryMetadata;
110
111
112 private final boolean useAttitudeFrame;
113
114
115 private boolean headerWritePending;
116
117
118 private double lastZ;
119
120
121
122
123
124
125
126
127
128
129
130
131 public StreamingOcmWriter(final Generator generator, final OcmWriter writer,
132 final OdmHeader header, final OcmMetadata metadata,
133 final TrajectoryStateHistoryMetadata template) {
134 this(generator, writer, header, metadata, template, true);
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 public StreamingOcmWriter(final Generator generator, final OcmWriter writer,
152 final OdmHeader header, final OcmMetadata metadata,
153 final TrajectoryStateHistoryMetadata template,
154 final boolean useAttitudeFrame) {
155 this.generator = generator;
156 this.writer = writer;
157 this.header = header;
158 this.metadata = metadata;
159 this.trajectoryMetadata = template.copy(header == null ? writer.getDefaultVersion() : header.getFormatVersion());
160 this.useAttitudeFrame = useAttitudeFrame;
161 this.headerWritePending = true;
162 this.lastZ = Double.NaN;
163 }
164
165
166
167
168
169
170
171 public BlockWriter newBlock() {
172 return new BlockWriter();
173 }
174
175
176 @Override
177 public void close() throws IOException {
178 writer.writeFooter(generator);
179 }
180
181
182 public class BlockWriter implements OrekitFixedStepHandler {
183
184
185 private Frame frame;
186
187
188 private OrbitElementsType type;
189
190
191 private int crossings;
192
193
194
195
196
197
198
199
200 public BlockWriter() {
201
202 }
203
204
205
206
207
208
209
210
211 @Override
212 public void init(final SpacecraftState s0, final AbsoluteDate t, final double step) {
213 try {
214 final AbsoluteDate date = s0.getDate();
215 if (t.isBefore(date)) {
216 throw new OrekitException(OrekitMessages.NON_CHRONOLOGICALLY_SORTED_ENTRIES,
217 date, t, date.durationFrom(t));
218 }
219
220 if (headerWritePending) {
221
222 writer.writeHeader(generator, header);
223 if (generator.getFormat() == FileFormat.XML) {
224 generator.enterSection(XmlStructureKey.segment.name());
225 }
226 new OcmMetadataWriter(metadata, writer.getTimeConverter()).write(generator);
227 if (generator.getFormat() == FileFormat.XML) {
228 generator.enterSection(XmlStructureKey.data.name());
229 }
230 headerWritePending = false;
231 }
232
233 trajectoryMetadata.setTrajNextID(TrajectoryStateHistoryMetadata.incrementTrajID(trajectoryMetadata.getTrajID()));
234 trajectoryMetadata.setUseableStartTime(date);
235 trajectoryMetadata.setUseableStopTime(t);
236 if (useAttitudeFrame) {
237 frame = s0.getAttitude().getReferenceFrame();
238 trajectoryMetadata.setTrajReferenceFrame(FrameFacade.map(frame));
239 } else {
240 frame = trajectoryMetadata.getTrajReferenceFrame().asFrame();
241 }
242
243 crossings = 0;
244 type = trajectoryMetadata.getTrajType();
245
246 final OneAxisEllipsoid body = trajectoryMetadata.getTrajType() == OrbitElementsType.GEODETIC ?
247 new OneAxisEllipsoid(writer.getEquatorialRadius(),
248 writer.getFlattening(),
249 trajectoryMetadata.getTrajReferenceFrame().asFrame()) :
250 null;
251 final double mu = s0.isOrbitDefined() ? s0.getOrbit().getMu() : Double.NaN;
252 trajectoryWriter = new TrajectoryStateHistoryWriter(new TrajectoryStateHistory(trajectoryMetadata,
253 Collections.emptyList(),
254 body, mu),
255 writer.getTimeConverter());
256 trajectoryWriter.enterSection(generator);
257 trajectoryWriter.writeMetadata(generator);
258
259 } catch (IOException e) {
260 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
261 }
262 }
263
264
265 @Override
266 public void handleStep(final SpacecraftState currentState) {
267 try {
268 final TimeStampedPVCoordinates pv =
269 currentState.getPVCoordinates(frame);
270 if (lastZ < 0.0 && pv.getPosition().getZ() >= 0.0) {
271
272 ++crossings;
273 }
274 final double mu = currentState.isOrbitDefined() ? currentState.getOrbit().getMu() : Double.NaN;
275 lastZ = pv.getPosition().getZ();
276 final TrajectoryState state = new TrajectoryState(type, pv.getDate(),
277 type.toRawElements(pv, frame,
278 trajectoryWriter.getHistory().getBody(),
279 mu));
280 trajectoryWriter.writeState(generator, state, type.getUnits());
281 } catch (IOException e) {
282 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
283 }
284 }
285
286
287 @Override
288 public void finish(final SpacecraftState finalState) {
289 try {
290
291 trajectoryWriter.exitSection(generator);
292
293
294 trajectoryMetadata.setTrajPrevID(trajectoryMetadata.getTrajID());
295 trajectoryMetadata.setTrajID(trajectoryMetadata.getTrajNextID());
296
297 if (trajectoryMetadata.getOrbRevNum() >= 0) {
298
299 trajectoryMetadata.setOrbRevNum(trajectoryMetadata.getOrbRevNum() + crossings);
300 }
301
302 } catch (IOException e) {
303 throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
304 }
305 }
306
307 }
308
309 }