OEMWriter.java
- /* Copyright 2016 Applied Defense Solutions (ADS)
- * Licensed to CS Systèmes d'Information (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * ADS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.files.ccsds;
- import java.io.IOException;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitIllegalArgumentException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.files.ccsds.StreamingOemWriter.Segment;
- import org.orekit.files.general.EphemerisFile;
- import org.orekit.files.general.EphemerisFile.EphemerisSegment;
- import org.orekit.files.general.EphemerisFileWriter;
- import org.orekit.time.TimeScale;
- import org.orekit.utils.TimeStampedPVCoordinates;
- /**
- * An OEM Writer class that can take in a general {@link EphemerisFile} object
- * and export it as a valid OEM file.
- *
- * @author Hank Grabowski
- * @author Evan Ward
- * @since 9.0
- * @see <a href="https://public.ccsds.org/Pubs/502x0b2c1.pdf">CCSDS 502.0-B-2 Orbit Data
- * Messages</a>
- * @see <a href="https://public.ccsds.org/Pubs/500x0g3.pdf">CCSDS 500.0-G-3 Navigation
- * Data Definitions and Conventions</a>
- * @see StreamingOemWriter
- */
- public class OEMWriter implements EphemerisFileWriter {
- /** Version number implemented. **/
- public static final String CCSDS_OEM_VERS = "2.0";
- /** Default interpolation method if the user specifies none. **/
- public static final InterpolationMethod DEFAULT_INTERPOLATION_METHOD = InterpolationMethod.LAGRANGE;
- /** Default originator field value if user specifies none. **/
- public static final String DEFAULT_ORIGINATOR = "OREKIT";
- /**
- * The space object ID we want to export, or null if we will process
- * whichever space object is in an {@link EphemerisFile} with only one space
- * object in it.
- */
- private final InterpolationMethod interpolationMethod;
- /** Originator name, usually the organization and/or country. **/
- private final String originator;
- /**
- * Space object ID, usually an official international designator such as
- * "1998-067A".
- **/
- private final String spaceObjectId;
- /** Space object name, usually a common name for an object like "ISS". **/
- private final String spaceObjectName;
- /**
- * Standard default constructor that creates a writer with default
- * configurations.
- */
- public OEMWriter() {
- this(DEFAULT_INTERPOLATION_METHOD, DEFAULT_ORIGINATOR, null, null);
- }
- /**
- * Constructor used to create a new OEM writer configured with the necessary
- * parameters to successfully fill in all required fields that aren't part
- * of a standard @{link EphemerisFile} object.
- *
- * @param interpolationMethod
- * The interpolation method to specify in the OEM file
- * @param originator
- * The originator field string
- * @param spaceObjectId
- * The spacecraft ID
- * @param spaceObjectName
- * The space object common name
- */
- public OEMWriter(final InterpolationMethod interpolationMethod, final String originator, final String spaceObjectId,
- final String spaceObjectName) {
- this.interpolationMethod = interpolationMethod;
- this.originator = originator;
- this.spaceObjectId = spaceObjectId;
- this.spaceObjectName = spaceObjectName;
- }
- /** {@inheritDoc} */
- @Override
- public void write(final Appendable writer, final EphemerisFile ephemerisFile)
- throws OrekitException, IOException {
- if (writer == null) {
- throw new OrekitIllegalArgumentException(OrekitMessages.NULL_ARGUMENT, "writer");
- }
- if (ephemerisFile == null) {
- return;
- }
- final String idToProcess;
- if (spaceObjectId != null) {
- if (ephemerisFile.getSatellites().containsKey(spaceObjectId)) {
- idToProcess = spaceObjectId;
- } else {
- throw new OrekitIllegalArgumentException(OrekitMessages.VALUE_NOT_FOUND, spaceObjectId, "ephemerisFile");
- }
- } else if (ephemerisFile.getSatellites().keySet().size() == 1) {
- idToProcess = ephemerisFile.getSatellites().keySet().iterator().next();
- } else {
- throw new OrekitIllegalArgumentException(OrekitMessages.EPHEMERIS_FILE_NO_MULTI_SUPPORT);
- }
- // Get satellite and ephemeris segments to output.
- final EphemerisFile.SatelliteEphemeris satEphem = ephemerisFile.getSatellites().get(idToProcess);
- final List<? extends EphemerisSegment> segments = satEphem.getSegments();
- if (segments.isEmpty()) {
- // no data -> no output
- return;
- }
- final EphemerisSegment firstSegment = segments.get(0);
- final String objectName = this.spaceObjectName == null ?
- idToProcess : this.spaceObjectName;
- // Only one time scale per OEM file, see Section 5.2.4.5
- final TimeScale timeScale = firstSegment.getTimeScale();
- // metadata that is constant for the whole OEM file
- final Map<Keyword, String> metadata = new LinkedHashMap<>();
- metadata.put(Keyword.TIME_SYSTEM, firstSegment.getTimeScaleString());
- metadata.put(Keyword.ORIGINATOR, this.originator);
- // Only one object in an OEM file, see Section 2.1
- metadata.put(Keyword.OBJECT_ID, idToProcess);
- metadata.put(Keyword.OBJECT_NAME, objectName);
- metadata.put(Keyword.INTERPOLATION, this.interpolationMethod.toString());
- final StreamingOemWriter oemWriter =
- new StreamingOemWriter(writer, timeScale, metadata);
- oemWriter.writeHeader();
- for (final EphemerisSegment segment : segments) {
- // segment specific metadata
- metadata.clear();
- metadata.put(Keyword.CENTER_NAME, segment.getFrameCenterString());
- metadata.put(Keyword.REF_FRAME, segment.getFrameString());
- metadata.put(Keyword.START_TIME, segment.getStart().toString(timeScale));
- metadata.put(Keyword.STOP_TIME, segment.getStop().toString(timeScale));
- metadata.put(Keyword.INTERPOLATION_DEGREE,
- String.valueOf(segment.getInterpolationSamples() - 1));
- final Segment segmentWriter = oemWriter.newSegment(null, metadata);
- segmentWriter.writeMetadata();
- for (final TimeStampedPVCoordinates coordinates : segment.getCoordinates()) {
- segmentWriter.writeEphemerisLine(coordinates);
- }
- }
- }
- /** OEM interpolation method. See Table 5-3. */
- public enum InterpolationMethod {
- /** Hermite interpolation. */
- HERMITE,
- /** Lagrange interpolation. */
- LAGRANGE,
- /** Linear interpolation. */
- LINEAR
- }
- }