Commit f07528d5 authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Allow to configure a spin axis for APM and AEM.

parent b265d4a1
......@@ -16,6 +16,7 @@
*/
package org.orekit.files.ccsds.ndm;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.data.DataContext;
import org.orekit.files.ccsds.ndm.adm.aem.AemParser;
import org.orekit.files.ccsds.ndm.adm.apm.ApmParser;
......@@ -41,34 +42,40 @@ public abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
/** Reference date for Mission Elapsed Time or Mission Relative Time time systems. */
private final AbsoluteDate missionReferenceDate;
/** Spin axis in spacecraft body frame. */
private final Vector3D spinAxis;
/**
* Complete constructor.
* @param conventions IERS Conventions
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* @param spinAxis spin axis in spacecraft body frame
*/
protected AbstractBuilder(final IERSConventions conventions, final DataContext dataContext,
final AbsoluteDate missionReferenceDate) {
final AbsoluteDate missionReferenceDate, final Vector3D spinAxis) {
this.conventions = conventions;
this.dataContext = dataContext;
this.missionReferenceDate = missionReferenceDate;
this.spinAxis = spinAxis;
}
/** Build an instance.
* @param newConventions IERS Conventions
* @param newDataContext used to retrieve frames, time scales, etc.
* @param newMissionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* @param newSpinAxis spin axis in spacecraft body frame
* @return new instance
*/
protected abstract T create(IERSConventions newConventions, DataContext newDataContext,
AbsoluteDate newMissionReferenceDate);
AbsoluteDate newMissionReferenceDate, Vector3D newSpinAxis);
/** Set up IERS conventions.
* @param newConventions IERS Conventions
* @return a new builder with updated configuration (the instance is not changed)
*/
public T withConventions(final IERSConventions newConventions) {
return create(newConventions, getDataContext(), getMissionReferenceDate());
return create(newConventions, getDataContext(), getMissionReferenceDate(), getSpinAxis());
}
/** Get the IERS conventions.
......@@ -83,7 +90,7 @@ public abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public T withDataContext(final DataContext newDataContext) {
return create(getConventions(), newDataContext, getMissionReferenceDate());
return create(getConventions(), newDataContext, getMissionReferenceDate(), getSpinAxis());
}
/** Get the data context.
......@@ -104,7 +111,7 @@ public abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public T withMissionReferenceDate(final AbsoluteDate newMissionReferenceDate) {
return create(getConventions(), getDataContext(), newMissionReferenceDate);
return create(getConventions(), getDataContext(), newMissionReferenceDate, getSpinAxis());
}
/** Get the mission reference date or Mission Elapsed Time or Mission Relative Time time systems.
......@@ -114,4 +121,23 @@ public abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
return missionReferenceDate;
}
/** Set up spin axis direction.
* <p>
* The spin axis is used only by {@link AemParser} and {@link ApmParser}.
* </p>
* @param newSpinAxis spin axis in spacecraft body frame
* @return a new builder with updated configuration (the instance is not changed)
*/
public T withSpinAxis(final Vector3D newSpinAxis) {
return create(getConventions(), getDataContext(), getMissionReferenceDate(), newSpinAxis);
}
/**
* Get spin axis in spacecraft body frame.
* @return spin axis
*/
public Vector3D getSpinAxis() {
return spinAxis;
}
}
......@@ -16,6 +16,7 @@
*/
package org.orekit.files.ccsds.ndm;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.data.DataContext;
import org.orekit.files.ccsds.ndm.adm.aem.AemParser;
......@@ -95,7 +96,7 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @param dataContext data context used to retrieve frames, time scales, etc.
*/
public ParserBuilder(final DataContext dataContext) {
this(IERSConventions.IERS_2010, dataContext, null, true, Double.NaN,
this(IERSConventions.IERS_2010, dataContext, null, null, true, Double.NaN,
Double.NaN, 1, ParsedUnitsBehavior.CONVERT_COMPATIBLE);
}
......@@ -103,6 +104,7 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @param conventions IERS Conventions
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* @param spinAxis spin axis in spacecraft body frame
* @param simpleEOP if true, tidal effects are ignored when interpolating EOP
* @param mu gravitational coefficient
* @param defaultMass default mass
......@@ -110,11 +112,11 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @param parsedUnitsBehavior behavior to adopt for handling parsed units
*/
private ParserBuilder(final IERSConventions conventions, final DataContext dataContext,
final AbsoluteDate missionReferenceDate, final boolean simpleEOP,
final double mu, final double defaultMass,
final AbsoluteDate missionReferenceDate, final Vector3D spinAxis,
final boolean simpleEOP, final double mu, final double defaultMass,
final int defaultInterpolationDegree,
final ParsedUnitsBehavior parsedUnitsBehavior) {
super(conventions, dataContext, missionReferenceDate);
super(conventions, dataContext, missionReferenceDate, spinAxis);
this.simpleEOP = simpleEOP;
this.mu = mu;
this.defaultMass = defaultMass;
......@@ -125,8 +127,8 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
/** {@inheritDoc} */
@Override
protected ParserBuilder create(final IERSConventions newConventions, final DataContext newDataContext,
final AbsoluteDate newMissionReferenceDate) {
return new ParserBuilder(newConventions, newDataContext, newMissionReferenceDate,
final AbsoluteDate newMissionReferenceDate, final Vector3D spinAxis) {
return new ParserBuilder(newConventions, newDataContext, newMissionReferenceDate, spinAxis,
simpleEOP, mu, defaultMass, defaultInterpolationDegree,
parsedUnitsBehavior);
}
......@@ -136,7 +138,8 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public ParserBuilder withSimpleEOP(final boolean newSimpleEOP) {
return new ParserBuilder(getConventions(), getDataContext(), getMissionReferenceDate(),
return new ParserBuilder(getConventions(), getDataContext(),
getMissionReferenceDate(), getSpinAxis(),
newSimpleEOP, getMu(), getDefaultMass(),
getDefaultInterpolationDegree(), getParsedUnitsBehavior());
}
......@@ -153,7 +156,8 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public ParserBuilder withMu(final double newMu) {
return new ParserBuilder(getConventions(), getDataContext(), getMissionReferenceDate(),
return new ParserBuilder(getConventions(), getDataContext(),
getMissionReferenceDate(), getSpinAxis(),
isSimpleEOP(), newMu, getDefaultMass(),
getDefaultInterpolationDegree(), getParsedUnitsBehavior());
}
......@@ -173,7 +177,8 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public ParserBuilder withDefaultMass(final double newDefaultMass) {
return new ParserBuilder(getConventions(), getDataContext(), getMissionReferenceDate(),
return new ParserBuilder(getConventions(), getDataContext(),
getMissionReferenceDate(), getSpinAxis(),
isSimpleEOP(), getMu(), newDefaultMass,
getDefaultInterpolationDegree(), getParsedUnitsBehavior());
}
......@@ -194,7 +199,8 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public ParserBuilder withDefaultInterpolationDegree(final int newDefaultInterpolationDegree) {
return new ParserBuilder(getConventions(), getDataContext(), getMissionReferenceDate(),
return new ParserBuilder(getConventions(), getDataContext(),
getMissionReferenceDate(), getSpinAxis(),
isSimpleEOP(), getMu(), getDefaultMass(),
newDefaultInterpolationDegree, getParsedUnitsBehavior());
}
......@@ -211,7 +217,8 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
* @return a new builder with updated configuration (the instance is not changed)
*/
public ParserBuilder withParsedUnitsBehavior(final ParsedUnitsBehavior newParsedUnitsBehavior) {
return new ParserBuilder(getConventions(), getDataContext(), getMissionReferenceDate(),
return new ParserBuilder(getConventions(), getDataContext(),
getMissionReferenceDate(), getSpinAxis(),
isSimpleEOP(), getMu(), getDefaultMass(),
getDefaultInterpolationDegree(), newParsedUnitsBehavior);
}
......@@ -259,7 +266,7 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
*/
public ApmParser buildApmParser() {
return new ApmParser(getConventions(), isSimpleEOP(), getDataContext(),
getMissionReferenceDate(), getParsedUnitsBehavior());
getMissionReferenceDate(), getSpinAxis(), getParsedUnitsBehavior());
}
/** Build a parser for {@link org.orekit.files.ccsds.ndm.adm.aem.AemFile Attitude Ephemeris Messages}.
......@@ -267,7 +274,7 @@ public class ParserBuilder extends AbstractBuilder<ParserBuilder> {
*/
public AemParser buildAemParser() {
return new AemParser(getConventions(), isSimpleEOP(), getDataContext(), getMissionReferenceDate(),
getDefaultInterpolationDegree(), getParsedUnitsBehavior());
getDefaultInterpolationDegree(), getSpinAxis(), getParsedUnitsBehavior());
}
/** Build a parser for {@link org.orekit.files.ccsds.ndm.tdm.TdmFile Tracking Data Messages}.
......
......@@ -16,6 +16,7 @@
*/
package org.orekit.files.ccsds.ndm;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.data.DataContext;
import org.orekit.files.ccsds.ndm.adm.aem.AemWriter;
......@@ -70,24 +71,25 @@ public class WriterBuilder extends AbstractBuilder<WriterBuilder> {
* @param dataContext data context used to retrieve frames, time scales, etc.
*/
public WriterBuilder(final DataContext dataContext) {
this(IERSConventions.IERS_2010, dataContext, null);
this(IERSConventions.IERS_2010, dataContext, null, null);
}
/** Complete constructor.
* @param conventions IERS Conventions
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* @param spinAxis spin axis in spacecraft body frame
*/
private WriterBuilder(final IERSConventions conventions, final DataContext dataContext,
final AbsoluteDate missionReferenceDate) {
super(conventions, dataContext, missionReferenceDate);
final AbsoluteDate missionReferenceDate, final Vector3D spinAxis) {
super(conventions, dataContext, missionReferenceDate, spinAxis);
}
/** {@inheritDoc} */
@Override
protected WriterBuilder create(final IERSConventions newConventions, final DataContext newDataContext,
final AbsoluteDate newMissionReferenceDate) {
return new WriterBuilder(newConventions, newDataContext, newMissionReferenceDate);
final AbsoluteDate newMissionReferenceDate, final Vector3D newSpinAxis) {
return new WriterBuilder(newConventions, newDataContext, newMissionReferenceDate, newSpinAxis);
}
/** Build a writer for {@link org.orekit.files.ccsds.ndm.odm.opm.OpmFile Orbit Parameters Messages}.
......@@ -122,14 +124,14 @@ public class WriterBuilder extends AbstractBuilder<WriterBuilder> {
* @return a new writer
*/
public ApmWriter buildApmWriter() {
return new ApmWriter(getConventions(), getDataContext(), getMissionReferenceDate());
return new ApmWriter(getConventions(), getDataContext(), getMissionReferenceDate(), getSpinAxis());
}
/** Build a writer for {@link org.orekit.files.ccsds.ndm.adm.aem.AemFile Attitude Ephemeris Messages}.
* @return a new writer
*/
public AemWriter buildAemWriter() {
return new AemWriter(getConventions(), getDataContext(), getMissionReferenceDate());
return new AemWriter(getConventions(), getDataContext(), getMissionReferenceDate(), getSpinAxis());
}
/** Build a writer for {@link org.orekit.files.ccsds.ndm.tdm.TdmFile Tracking Data Messages}.
......
......@@ -19,6 +19,7 @@ package org.orekit.files.ccsds.ndm.adm;
import java.util.Map;
import org.hipparchus.geometry.euclidean.threed.RotationOrder;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.data.DataContext;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
......@@ -62,6 +63,9 @@ public abstract class AdmParser<T extends NdmFile<?, ?>, P extends AbstractMessa
/** Reference date for Mission Elapsed Time or Mission Relative Time time systems. */
private final AbsoluteDate missionReferenceDate;
/** Spin axis in spacecraft body frame. */
private final Vector3D spinAxis;
/** Complete constructor.
* @param root root element for XML files
* @param formatVersionKey key for format version
......@@ -70,13 +74,17 @@ public abstract class AdmParser<T extends NdmFile<?, ?>, P extends AbstractMessa
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* (may be null if time system is absolute)
* @param spinAxis spin axis in spacecraft body frame
* (may be null if attitude type is neither spin nor spin/nutation)
* @param parsedUnitsBehavior behavior to adopt for handling parsed units
*/
protected AdmParser(final String root, final String formatVersionKey, final IERSConventions conventions,
final boolean simpleEOP, final DataContext dataContext,
final AbsoluteDate missionReferenceDate, final ParsedUnitsBehavior parsedUnitsBehavior) {
final AbsoluteDate missionReferenceDate, final Vector3D spinAxis,
final ParsedUnitsBehavior parsedUnitsBehavior) {
super(root, formatVersionKey, conventions, simpleEOP, dataContext, parsedUnitsBehavior);
this.missionReferenceDate = missionReferenceDate;
this.spinAxis = spinAxis;
}
/** {@inheritDoc} */
......@@ -102,6 +110,14 @@ public abstract class AdmParser<T extends NdmFile<?, ?>, P extends AbstractMessa
return missionReferenceDate;
}
/**
* Get spin axis in spacecraft body frame.
* @return spin axis
*/
public Vector3D getSpinAxis() {
return spinAxis;
}
/** Process a CCSDS Euler angles sequence as a {@link RotationOrder}.
* @param sequence Euler angles sequence token
* @param consumer consumer of the rotation order
......
......@@ -77,8 +77,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
Rotation rotation = isFirst ?
new Rotation(components[0], components[1], components[2], components[3], true) :
......@@ -138,8 +138,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
FieldRotation<UnivariateDerivative1> rotation =
isFirst ?
new FieldRotation<>(new UnivariateDerivative1(components[0], components[4]),
......@@ -202,8 +202,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
// Build the needed objects
final Rotation rotation = isFirst ?
new Rotation(components[0], components[1], components[2], components[3], true) :
......@@ -252,8 +252,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
// Build the needed objects
Rotation rotation = new Rotation(eulerRotSequence, RotationConvention.FRAME_TRANSFORM,
......@@ -305,8 +305,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
// Build the needed objects
final Rotation rotation = new Rotation(eulerRotSequence,
......@@ -349,8 +349,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
// Attitude parameters in the Specified Reference Frame for a Spin Stabilized Satellite
// are optional in CCSDS AEM format. Support for this attitude type is not implemented
// yet in Orekit.
......@@ -381,8 +381,8 @@ public enum AttitudeType {
final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence,
final boolean isSpacecraftBodyRate,
final AbsoluteDate date,
final double...components) {
final Vector3D spinAxis,
final AbsoluteDate date, final double...components) {
// Attitude parameters in the Specified Reference Frame for a Spin Stabilized Satellite
// are optional in CCSDS AEM format. Support for this attitude type is not implemented
// yet in Orekit.
......@@ -454,6 +454,7 @@ public enum AttitudeType {
* @param isExternal2SpacecraftBody true attitude is from external frame to spacecraft body frame
* @param eulerRotSequence sequance of Euler angles
* @param isSpacecraftBodyRate if true Euler rates are specified in spacecraft body frame
* @param spinAxis spin axis in spacecraft body frame
* @param context context binding
* @param fields raw data fields
* @return the angular coordinates, using {@link Attitude Attitude} convention
......@@ -461,7 +462,7 @@ public enum AttitudeType {
*/
public TimeStampedAngularCoordinates parse(final boolean isFirst, final boolean isExternal2SpacecraftBody,
final RotationOrder eulerRotSequence, final boolean isSpacecraftBodyRate,
final ContextBinding context,
final Vector3D spinAxis, final ContextBinding context,
final String[] fields) {
// parse the text fields
......@@ -473,7 +474,7 @@ public enum AttitudeType {
// build the coordinates
return build(isFirst, isExternal2SpacecraftBody, eulerRotSequence, isSpacecraftBodyRate,
date, components);
spinAxis, date, components);
}
......@@ -482,6 +483,7 @@ public enum AttitudeType {
* @param isExternal2SpacecraftBody true attitude is from external frame to spacecraft body frame
* @param eulerRotSequence sequance of Euler angles
* @param isSpacecraftBodyRate if true Euler rates are specified in spacecraft body frame
* @param spinAxis spin axis in spacecraft body frame
* @param date entry date
* @param components entry components with CCSDS units (i.e. angles
* <em>must</em> still be in degrees here), semantic depends on attitude type
......@@ -490,7 +492,7 @@ public enum AttitudeType {
*/
public abstract TimeStampedAngularCoordinates build(boolean isFirst, boolean isExternal2SpacecraftBody,
RotationOrder eulerRotSequence, boolean isSpacecraftBodyRate,
AbsoluteDate date, double...components);
Vector3D spinAxis, AbsoluteDate date, double...components);
/**
* Get the angular derivative filter corresponding to the attitude data.
......
......@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.data.DataContext;
import org.orekit.data.DataSource;
import org.orekit.errors.OrekitException;
......@@ -95,14 +96,17 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* (may be null if time system is absolute)
* @param spinAxis spin axis in spacecraft body frame
* (may be null if attitude type is neither spin nor spin/nutation)
* @param defaultInterpolationDegree default interpolation degree
* @param parsedUnitsBehavior behavior to adopt for handling parsed units
*/
public AemParser(final IERSConventions conventions, final boolean simpleEOP,
final DataContext dataContext, final AbsoluteDate missionReferenceDate,
final int defaultInterpolationDegree, final ParsedUnitsBehavior parsedUnitsBehavior) {
final int defaultInterpolationDegree, final Vector3D spinAxis,
final ParsedUnitsBehavior parsedUnitsBehavior) {
super(AemFile.ROOT, AemFile.FORMAT_VERSION_KEY, conventions, simpleEOP, dataContext,
missionReferenceDate, parsedUnitsBehavior);
missionReferenceDate, spinAxis, parsedUnitsBehavior);
this.defaultInterpolationDegree = defaultInterpolationDegree;
}
......@@ -165,7 +169,8 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
context = new ContextBinding(this::getConventions, this::isSimpleEOP,
this::getDataContext, this::getParsedUnitsBehavior,
this::getMissionReferenceDate,
metadata::getTimeSystem, () -> 0.0, () -> 1.0);
metadata::getTimeSystem, () -> 0.0, () -> 1.0,
this::getSpinAxis);
setFallback(this::processMetadataToken);
return true;
}
......@@ -300,8 +305,8 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
metadata.getEndpoints().isExternal2SpacecraftBody(),
metadata.getEulerRotSeq(),
metadata.isSpacecraftBodyRate(),
context,
SPLIT_AT_BLANKS.split(token.getRawContent().trim())));
null,
context, SPLIT_AT_BLANKS.split(token.getRawContent().trim())));
} catch (NumberFormatException nfe) {
throw new OrekitException(nfe, OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
token.getLineNumber(), token.getFileName(), token.getRawContent());
......
......@@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.Date;
import org.hipparchus.geometry.euclidean.threed.RotationOrder;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.data.DataContext;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitInternalError;
......@@ -273,16 +274,17 @@ public class AemWriter extends AbstractMessageWriter<Header, AemSegment, AemFile
* @param conventions IERS Conventions
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* @param spinAxis spin axis in spacecraft body frame
* @since 11.0
*/
public AemWriter(final IERSConventions conventions, final DataContext dataContext,
final AbsoluteDate missionReferenceDate) {
final AbsoluteDate missionReferenceDate, final Vector3D spinAxis) {
super(AemFile.ROOT, AemFile.FORMAT_VERSION_KEY, CCSDS_AEM_VERS,
new ContextBinding(
() -> conventions,
() -> true, () -> dataContext, () -> ParsedUnitsBehavior.STRICT_COMPLIANCE,
() -> missionReferenceDate, () -> TimeSystem.UTC,
() -> 0.0, () -> 1.0));
() -> 0.0, () -> 1.0, () -> spinAxis));
}
/** {@inheritDoc} */
......@@ -317,7 +319,8 @@ public class AemWriter extends AbstractMessageWriter<Header, AemSegment, AemFile
oldContext::getReferenceDate,
metadata::getTimeSystem,
oldContext::getClockCount,
oldContext::getClockRate));
oldContext::getClockRate,
oldContext::getSpinAxis));
// Start metadata
generator.enterSection(generator.getFormat() == FileFormat.KVN ?
......
......@@ -111,8 +111,8 @@ class AttitudeEntry {
metadata.getEndpoints().isExternal2SpacecraftBody(),
metadata.getEulerRotSeq(),
metadata.isSpacecraftBodyRate(),
epoch,
components);
null,
epoch, components);
}
}
......@@ -86,9 +86,9 @@ public class ApmFile extends NdmFile<Header, Segment<AdmMetadata, ApmData>> {
final Quaternion qDot = qBlock.getQuaternionDot();
tac = AttitudeType.QUATERNION_DERIVATIVE.build(true, qBlock.getEndpoints().isExternal2SpacecraftBody(),
null, true,
qBlock.getEpoch(),
q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3(),
qDot.getQ0(), qDot.getQ1(), qDot.getQ2(), qDot.getQ3());
null,
qBlock.getEpoch(), q.getQ0(), q.getQ1(), q.getQ2(),
q.getQ3(), qDot.getQ0(), qDot.getQ1(), qDot.getQ2(), qDot.getQ3());
} else if (eBlock != null && eBlock.hasRates()) {
// we have to rely on the Euler logical block to take rates into account
......@@ -107,17 +107,17 @@ public class ApmFile extends NdmFile<Header, Segment<AdmMetadata, ApmData>> {
qBlock.getEndpoints().isExternal2SpacecraftBody(),
eBlock.getEulerRotSeq(),
eBlock.isSpacecraftBodyRate(),
qBlock.getEpoch(),
q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3(),
rates[0], rates[1], rates[2]);
null,
qBlock.getEpoch(), q.getQ0(), q.getQ1(), q.getQ2(),
q.getQ3(), rates[0], rates[1], rates[2]);
} else {
// we rely only on the quaternion logical block, despite it doesn't include rates
final Quaternion q = qBlock.getQuaternion();
tac = AttitudeType.QUATERNION.build(true, qBlock.getEndpoints().isExternal2SpacecraftBody(),
null, true,
qBlock.getEpoch(),
q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3());
null,
qBlock.getEpoch(), q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3());
}
// build the attitude
......
......@@ -19,6 +19,7 @@ package org.orekit.files.ccsds.ndm.adm.apm;
import java.util.ArrayList;
import java.util.List;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.data.DataContext;
import org.orekit.files.ccsds.ndm.ParsedUnitsBehavior;
import org.orekit.files.ccsds.ndm.adm.AdmMetadata;
......@@ -102,12 +103,15 @@ public class ApmParser extends AdmParser<ApmFile, ApmParser> {
* @param dataContext used to retrieve frames, time scales, etc.
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* (may be null if time system is absolute)
* @param spinAxis spin axis in spacecraft body frame
* (may be null if attitude type is neither spin nor spin/nutation)
* @param parsedUnitsBehavior behavior to adopt for handling parsed units
*/
public ApmParser(final IERSConventions conventions, final boolean simpleEOP, final DataContext dataContext,
final AbsoluteDate missionReferenceDate, final ParsedUnitsBehavior parsedUnitsBehavior) {