STKEphemerisFile.java
/* Copyright 2002-2024 Andrew Goetz
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS 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.stk;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.files.general.EphemerisFile;
import org.orekit.files.stk.STKEphemerisFile.STKEphemerisSegment;
import org.orekit.frames.Frame;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.CartesianDerivativesFilter;
import org.orekit.utils.TimeStampedPVCoordinates;
/**
* STK ephemeris file.
*
* @author Andrew Goetz
* @since 12.0
*/
public class STKEphemerisFile implements EphemerisFile<TimeStampedPVCoordinates, STKEphemerisSegment> {
/** STK version. */
private final String stkVersion;
/** Unmodifiable mapping with a single key-value pair from satellite id to ephemeris. */
private final Map<String, STKEphemeris> satellites;
/**
* Constructs a {@link STKEphemerisFile} instance.
* @param stkVersion STK version string (example: "stk.v.11.0")
* @param satelliteId satellite id
* @param ephemeris ephemeris
*/
public STKEphemerisFile(final String stkVersion, final String satelliteId, final STKEphemeris ephemeris) {
this.stkVersion = Objects.requireNonNull(stkVersion);
final Map<String, STKEphemeris> tempMap = new HashMap<>();
tempMap.put(satelliteId, ephemeris);
this.satellites = Collections.unmodifiableMap(tempMap);
}
/**
* Returns the STK version string.
* @return STK version string
*/
public String getSTKVersion() {
return stkVersion;
}
/**
* {@inheritDoc}
* <p>
* STK ephemeris files define ephemeris for a single satellite, so the returned
* map will have a single entry.
* </p>
*/
@Override
public Map<String, STKEphemeris> getSatellites() {
return satellites;
}
/**
* Ephemeris segment from an STK ephemeris file.
*/
public static class STKEphemerisSegment implements EphemerisFile.EphemerisSegment<TimeStampedPVCoordinates> {
/** Gravitational parameter (m^3/s^2). */
private final double mu;
/** Reference frame. */
private final Frame frame;
/** Number of samples to use in interpolation. */
private final int interpolationSamples;
/** Cartesian derivatives filter. */
private final CartesianDerivativesFilter cartesianDerivativesFilter;
/** Time-sorted time/position/velocity data. */
private final List<TimeStampedPVCoordinates> timeStampedPVCoordinates;
/**
* Constructs a {@link STKEphemerisSegment} instance.
* @param mu gravitational parameter (m^3/s^2)
* @param frame frame
* @param interpolationSamples number of samples to use in interpolation
* @param cartesianDerivativesFilter Cartesian derivatives filter
* @param timeStampedPVCoordinates time-sorted time/position/velocity data
*/
public STKEphemerisSegment(final double mu, final Frame frame, final int interpolationSamples,
final CartesianDerivativesFilter cartesianDerivativesFilter,
final List<TimeStampedPVCoordinates> timeStampedPVCoordinates) {
this.mu = mu;
this.frame = Objects.requireNonNull(frame);
this.interpolationSamples = interpolationSamples;
this.cartesianDerivativesFilter = Objects.requireNonNull(cartesianDerivativesFilter);
this.timeStampedPVCoordinates = Collections.unmodifiableList(new ArrayList<>(timeStampedPVCoordinates));
}
@Override
public double getMu() {
return mu;
}
@Override
public Frame getFrame() {
return frame;
}
@Override
public int getInterpolationSamples() {
return interpolationSamples;
}
@Override
public CartesianDerivativesFilter getAvailableDerivatives() {
return cartesianDerivativesFilter;
}
@Override
public List<TimeStampedPVCoordinates> getCoordinates() {
return timeStampedPVCoordinates;
}
@Override
public AbsoluteDate getStart() {
return timeStampedPVCoordinates.get(0).getDate();
}
@Override
public AbsoluteDate getStop() {
return timeStampedPVCoordinates.get(timeStampedPVCoordinates.size() - 1).getDate();
}
}
/**
* Ephemeris from an STK ephemeris file.
*/
public static class STKEphemeris implements SatelliteEphemeris<TimeStampedPVCoordinates, STKEphemerisSegment> {
/** Satellite id.*/
private final String satelliteId;
/** Gravitational parameter (m^3/s^2). */
private final double mu;
/** Unmodifiable list of ephemeris segments. */
private final List<STKEphemerisSegment> segments;
/**
* Constructs a {@link STKEphemeris} instance. This constructor shallowly copies the list of segments provided.
* @param satelliteId satellite id
* @param mu gravitational parameter (m^3/s^2)
* @param segments ephemeris segments
*/
public STKEphemeris(final String satelliteId, final double mu, final List<STKEphemerisSegment> segments) {
this.satelliteId = Objects.requireNonNull(satelliteId);
this.mu = mu;
this.segments = Collections.unmodifiableList(new ArrayList<>(segments));
}
@Override
public String getId() {
return satelliteId;
}
@Override
public double getMu() {
return mu;
}
@Override
public List<STKEphemerisSegment> getSegments() {
return segments;
}
@Override
public AbsoluteDate getStart() {
return segments.get(0).getStart();
}
@Override
public AbsoluteDate getStop() {
return segments.get(segments.size() - 1).getStop();
}
}
/**
* STK coordinate system.
* <p>
* Currently, only Earth-centered coordinate systems are supported.
* </p>
*/
public enum STKCoordinateSystem {
/** International Celestial Reference Frame. */
ICRF,
/** Mean equator and mean equinox of the J2000 epoch. */
J2000,
/** Central-body-dependent inertial frame, equivalent to ICRF for Earth. */
INERTIAL,
/** Fixed frame. */
FIXED,
/** True equator and true equinox of date. */
TRUE_OF_DATE,
/** Mean equator and mean equinox of date. */
MEAN_OF_DATE,
/** True equator and mean equinox of date. */
TEME_OF_DATE;
/**
* Parses a coordinate system from a string.
* @param s string
* @return coordinate system
*/
public static STKCoordinateSystem parse(final String s) {
final String sUpper = s.toUpperCase(Locale.US);
switch (sUpper) {
case "ICRF":
return ICRF;
case "J2000":
return J2000;
case "INERTIAL":
return INERTIAL;
case "FIXED":
return FIXED;
case "TRUEOFDATE":
return TRUE_OF_DATE;
case "MEANOFDATE":
return MEAN_OF_DATE;
case "TEMEOFDATE":
return TEME_OF_DATE;
default:
throw new OrekitException(OrekitMessages.STK_INVALID_OR_UNSUPPORTED_COORDINATE_SYSTEM, s);
}
}
}
}