ManeuverFieldType.java
- /* Copyright 2002-2025 CS GROUP
- * 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.ccsds.ndm.odm.ocm;
- import org.hipparchus.util.Precision;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.files.ccsds.definitions.OnOff;
- import org.orekit.files.ccsds.definitions.TimeConverter;
- import org.orekit.files.ccsds.utils.ContextBinding;
- import org.orekit.time.DateTimeComponents;
- import org.orekit.utils.AccurateFormatter;
- import org.orekit.utils.Formatter;
- import org.orekit.utils.units.Unit;
- /** Maneuver field type used in CCSDS {@link Ocm Orbit Comprehensive Messages}.
- * @author Luc Maisonobe
- * @since 11.0
- */
- public enum ManeuverFieldType {
- // CHECKSTYLE: stop MultipleStringLiterals check
- /** Absolute epoch time. */
- TIME_ABSOLUTE("n/a",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDate(context.getTimeSystem().getConverter(context).parse(field)),
- (u, converter, maneuver, formatter) -> {
- final DateTimeComponents dt = converter.components(maneuver.getDate());
- return formatter.toString(dt.getDate().getYear(), dt.getDate().getMonth(), dt.getDate().getDay(),
- dt.getTime().getHour(), dt.getTime().getMinute(), dt.getTime().getSecond());
- }),
- /** Relative epoch time. */
- TIME_RELATIVE("s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDate(context.getReferenceDate().shiftedBy(toSI(field, u))),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(converter.offset(maneuver.getDate())))),
- /** Maneuver duration. */
- MAN_DURA("s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDuration(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDuration()))),
- /** Mass change. */
- DELTA_MASS("kg",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeltaMass(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeltaMass()))),
- /** Acceleration along X axis. */
- ACC_X("km/s²",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setAcceleration(0, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getAcceleration().getX()))),
- /** Acceleration along Y axis. */
- ACC_Y("km/s²",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setAcceleration(1, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getAcceleration().getY()))),
- /** Acceleration along Z axis. */
- ACC_Z("km/s²",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setAcceleration(2, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getAcceleration().getZ()))),
- /** Interpolation mode between current and next acceleration line. */
- ACC_INTERP("n/a",
- (field, u, context, maneuver, lineNumber, fileName) -> {
- try {
- maneuver.setAccelerationInterpolation(OnOff.valueOf(field));
- } catch (IllegalArgumentException iae) {
- throw new OrekitException(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD,
- lineNumber, fileName, field);
- }
- },
- (u, converter, maneuver, formatter) -> maneuver.getAccelerationInterpolation().name()),
- /** One σ percent error on acceleration magnitude. */
- ACC_MAG_SIGMA("%",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setAccelerationMagnitudeSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getAccelerationMagnitudeSigma()))),
- /** One σ off-nominal acceleration direction. */
- ACC_DIR_SIGMA("°",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setAccelerationDirectionSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getAccelerationDirectionSigma()))),
- /** Velocity increment along X axis. */
- DV_X("km/s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDv(0, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDv().getX()))),
- /** Velocity increment along Y axis. */
- DV_Y("km/s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDv(1, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDv().getY()))),
- /** Velocity increment along Z axis. */
- DV_Z("km/s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDv(2, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDv().getZ()))),
- /** One σ percent error on ΔV magnitude. */
- DV_MAG_SIGMA("%",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDvMagSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDvMagSigma()))),
- /** One σ angular off-nominal ΔV direction. */
- DV_DIR_SIGMA("°",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDvDirSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDvDirSigma()))),
- /** Thrust component along X axis. */
- THR_X("N",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrust(0, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrust().getX()))),
- /** Thrust component along Y axis. */
- THR_Y("N",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrust(1, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrust().getY()))),
- /** Thrust component along Z axis. */
- THR_Z("N",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrust(2, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrust().getZ()))),
- /** Thrust efficiency η typically between 0.0 and 1.0. */
- THR_EFFIC("n/a",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrustEfficiency(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrustEfficiency()))),
- /** Interpolation mode between current and next acceleration line. */
- THR_INTERP("n/a",
- (field, u, context, maneuver, lineNumber, fileName) -> {
- try {
- maneuver.setThrustInterpolation(OnOff.valueOf(field));
- } catch (IllegalArgumentException iae) {
- throw new OrekitException(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD,
- lineNumber, fileName, field);
- }
- },
- (u, converter, maneuver, formatter) -> maneuver.getThrustInterpolation().name()),
- /** Thrust specific impulse. */
- THR_ISP("s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrustIsp(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrustIsp()))),
- /** One σ percent error on thrust magnitude. */
- THR_MAG_SIGMA("%",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrustMagnitudeSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrustMagnitudeSigma()))),
- /** One σ angular off-nominal thrust direction. */
- THR_DIR_SIGMA("°",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setThrustDirectionSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getThrustDirectionSigma()))),
- /** Identifier of resulting "child" object deployed from this host. */
- DEPLOY_ID("n/a",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployId(field),
- (u, converter, maneuver, formatter) -> maneuver.getDeployId()),
- /** Velocity increment of deployed "child" object along X axis. */
- DEPLOY_DV_X("km/s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDv(0, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDv().getX()))),
- /** Velocity increment of deployed "child" object along Y axis. */
- DEPLOY_DV_Y("km/s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDv(1, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDv().getY()))),
- /** Velocity increment of deployed "child" object along Z axis. */
- DEPLOY_DV_Z("km/s",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDv(2, toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDv().getZ()))),
- /** Decrement in host mass as a result of deployment (shall be ≤ 0). */
- DEPLOY_MASS("kg",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployMass(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployMass()))),
- /** One σ percent error on deployment ΔV magnitude. */
- DEPLOY_DV_SIGMA("%",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDvSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDvSigma()))),
- /** One σ angular off-nominal deployment vector direction. */
- DEPLOY_DIR_SIGMA("°",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDirSigma(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDirSigma()))),
- /** Ratio of child-to-host ΔV vectors. */
- DEPLOY_DV_RATIO("n/a",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDvRatio(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDvRatio()))),
- /** Typical (50th percentile) product of drag coefficient times cross-sectional area of deployed "child" object. */
- DEPLOY_DV_CDA("m²",
- (field, u, context, maneuver, lineNumber, fileName) -> maneuver.setDeployDvCda(toSI(field, u)),
- (u, converter, maneuver, formatter) -> formatter.toString(u.fromSI(maneuver.getDeployDvCda())));
- // CHECKSTYLE: resume MultipleStringLiterals check
- /** Elements units. */
- private final Unit unit;
- /** Processing method. */
- private final transient FieldProcessor processor;
- /** Writing method. */
- private final transient FieldWriter writer;
- /** Simple constructor.
- * @param unitSpecifications field unit specifications
- * @param processor field processing method
- * @param writer field writing method
- */
- ManeuverFieldType(final String unitSpecifications, final FieldProcessor processor, final FieldWriter writer) {
- this.unit = Unit.parse(unitSpecifications);
- this.processor = processor;
- this.writer = writer;
- }
- /** Get the field unit.
- * @return field unit
- */
- public Unit getUnit() {
- return unit;
- }
- /** Check if parsed unit is compatible with field type.
- * @param parsedUnit unit to check
- */
- public void checkUnit(final Unit parsedUnit) {
- if (unit == Unit.NONE ^ parsedUnit == Unit.NONE ||
- !(unit.sameDimension(parsedUnit) && Precision.equals(unit.getScale(), parsedUnit.getScale(), 1))) {
- throw new OrekitException(OrekitMessages.INCOMPATIBLE_UNITS,
- unit.getName(), parsedUnit.getName());
- }
- }
- /** Check if a field is a time field.
- * @return true if field is a time field
- */
- public boolean isTime() {
- return this == TIME_ABSOLUTE || this == TIME_RELATIVE;
- }
- /** Get the value in SI units corresponding to a field.
- * @param field text field
- * @param unit unit to use
- * @return double value in SI units
- */
- private static double toSI(final String field, final Unit unit) {
- return unit.toSI(Double.parseDouble(field));
- }
- /** Process one field.
- * @param field field to process
- * @param context context binding
- * @param maneuver maneuver to fill
- * @param lineNumber line number at which the field occurs
- * @param fileName name of the file in which the field occurs
- */
- public void process(final String field, final ContextBinding context, final OrbitManeuver maneuver,
- final int lineNumber, final String fileName) {
- processor.process(field, unit, context, maneuver, lineNumber, fileName);
- }
- /** Output one maneuver field.
- * @param converter converter for dates
- * @param maneuver maneuver containing the field to output
- * @param formatter used format doubles and dates to strings
- * @return output field
- */
- public String outputField(final TimeConverter converter, final OrbitManeuver maneuver, final Formatter formatter) {
- return writer.output(unit, converter, maneuver, formatter);
- }
- /** Output one maneuver field.
- * @param converter converter for dates
- * @param maneuver maneuver containing the field to output
- * @return output field
- * @deprecated since 13.0, because formatter should be specified. Use {@link ManeuverFieldType#outputField(TimeConverter, OrbitManeuver, Formatter)} instead.
- */
- @Deprecated
- public String outputField(final TimeConverter converter, final OrbitManeuver maneuver) {
- return writer.output(unit, converter, maneuver, new AccurateFormatter());
- }
- /** Interface for processing one field. */
- interface FieldProcessor {
- /** Process one field.
- * @param field field to process
- * @param unit unit to use
- * @param context context binding
- * @param maneuver maneuver to fill
- * @param lineNumber line number at which the field occurs
- * @param fileName name of the file in which the field occurs
- */
- void process(String field, Unit unit, ContextBinding context, OrbitManeuver maneuver,
- int lineNumber, String fileName);
- }
- /** Interface for writing one field based on formatting standards. */
- interface FieldWriter {
- /** Process one field.
- * @param unit unit to use
- * @param converter converter for dates
- * @param maneuver maneuver containing the field to output
- * @param formatter used to format dates and doubles to string
- * @return output field
- */
- String output(Unit unit, TimeConverter converter, OrbitManeuver maneuver, Formatter formatter);
- }
- }