Skip to content

AEM — Attitude Ephemeris Message

Parses CCSDS Attitude Ephemeris Messages containing time-ordered attitude segments across all nine 504.0-B-2 attitude data types, and converts segments to and from native AttitudeTrajectory objects.


AEM

AEM(originator: str)

A complete CCSDS Attitude Ephemeris Message.

Parameters:

Name Type Description Default
originator str

Creating agency or operator identifier

required
Example
1
2
3
import brahe as bh
from brahe.ccsds import AEM
aem = AEM("BRAHE")

Initialize instance.

classification property

classification: Any

str | None: Classification marking

creation_date property

creation_date: Tuple[int, ...]

Epoch: Creation date of the message

format_version property

format_version: Any

float: CCSDS format version

message_id property

message_id: Any

str | None: Message identifier, unique within the originator's context

originator property

originator: Any

str: Originator of the message

segments property

segments: Any

list[AEMSegment]: Attitude ephemeris segments (owned copies)

add_segment method descriptor

add_segment(segment: AEMSegment) -> int

Add a segment to the message.

Parameters:

Name Type Description Default
segment AEMSegment

Segment to append

required

Returns:

Name Type Description
int int

Index of the new segment

from_attitude_trajectory staticmethod

from_attitude_trajectory(traj: AttitudeTrajectory, object_name: str, object_id: str, originator: str, time_system: str) -> AEM

Build a single-segment AEM from a native AttitudeTrajectory.

ATTITUDE_TYPE is QUATERNION/ANGVEL when the trajectory carries angular velocity, otherwise QUATERNION. Frame endpoints convert via the reverse PR-1 frame bridge.

Parameters:

Name Type Description Default
traj AttitudeTrajectory

Trajectory to convert

required
object_name str

OBJECT_NAME metadata value

required
object_id str

OBJECT_ID metadata value

required
originator str

Message originator (creating agency or operator)

required
time_system str

Time system to record in TIME_SYSTEM

required

Returns:

Name Type Description
AEM AEM

Single-segment AEM

from_file staticmethod

from_file(path: str) -> AEM

Parse an AEM from a file, auto-detecting the format.

Parameters:

Name Type Description Default
path str

Path to the AEM file

required

Returns:

Name Type Description
AEM AEM

Parsed AEM message

from_str staticmethod

from_str(content: str) -> AEM

Parse an AEM from a string, auto-detecting the format.

Parameters:

Name Type Description Default
content str

String content of the AEM message

required

Returns:

Name Type Description
AEM AEM

Parsed AEM message

register_for method descriptor

register_for(name: str) -> None

Register this AEM's attitude as the orientation of name's body frame.

Converts the AEM to an AttitudeTrajectory (requiring exactly one segment) and registers it in the global frame registry as the link between the segment's two REF_FRAME endpoints. A CCSDS message names its frames but not the object they belong to, so the body endpoint is bound to name here. One endpoint must resolve to a CelestialFrame — that becomes the parent — and the other must be a body frame. The quaternion series is inverted when the celestial frame is endpoint B, so the registered orientation always rotates parent-frame vectors into the body frame.

Parameters:

Name Type Description Default
name str

The object identity to bind the body frame endpoint to

required

Raises:

Type Description
BraheError

If the AEM does not have exactly one segment, neither endpoint resolves to a celestial frame, or the remaining endpoint is not a body frame

Returns:

Name Type Description
None None

The frame is registered in the global frame registry

Example
1
2
3
4
5
6
7
import brahe as bh
from brahe.ccsds import AEM

aem = AEM.from_file("test_assets/ccsds/aem/AEMExampleG5.txt")
bh.clear_frame_registry()
aem.register_for("SC")
bh.clear_frame_registry()

segment_to_attitude_trajectory method descriptor

segment_to_attitude_trajectory(segment_idx: int) -> AttitudeTrajectory

Convert a single segment to an AttitudeTrajectory.

The SPIN* attitude types have no AttitudeTrajectory representation and raise an error (the message can still be read and written, but not converted). A segment with INTERPOLATION_METHOD = HERMITE also raises, since AttitudeTrajectory has no Hermite interpolation mode.

Parameters:

Name Type Description Default
segment_idx int

Index of the segment to convert

required

Returns:

Name Type Description
AttitudeTrajectory AttitudeTrajectory

Converted trajectory

to_attitude_trajectories method descriptor

to_attitude_trajectories() -> list[AttitudeTrajectory]

Convert all segments to AttitudeTrajectory objects.

Returns:

Type Description
list[AttitudeTrajectory]

list[AttitudeTrajectory]: Converted trajectories, one per segment

to_dict method descriptor

to_dict() -> dict

Convert the AEM to a Python dictionary.

Epochs are serialized as CCSDS datetime strings for JSON/dict compatibility.

Returns:

Name Type Description
dict dict

Dictionary representation of the AEM

to_file method descriptor

to_file(path: str, format: str) -> Any

Write the AEM to a file in the specified format.

Parameters:

Name Type Description Default
path str

Output file path

required
format str

Output format - "KVN", "XML", or "JSON"

required

to_json_string method descriptor

to_json_string(uppercase_keys: bool = False) -> str

Write the AEM to JSON with explicit key case control.

Parameters:

Name Type Description Default
uppercase_keys bool

If True, use uppercase CCSDS keywords. Default: False.

False

Returns:

Name Type Description
str str

Serialized JSON string

to_string method descriptor

to_string(format: str) -> str

Write the AEM to a string in the specified format.

Parameters:

Name Type Description Default
format str

Output format - "KVN", "XML", or "JSON"

required

Returns:

Name Type Description
str str

Serialized AEM string


AEMSegment

AEMSegment(object_name: str, object_id: str, ref_frame_a: str, ref_frame_b: str, time_system: str, start_time: Epoch, stop_time: Epoch, attitude_type: str, center_name: str | None = None, useable_start_time: Epoch | None = None, useable_stop_time: Epoch | None = None, euler_rot_seq: EulerAngleOrder | None = None, angvel_frame: str | None = None, interpolation_method: str | None = None, interpolation_degree: int | None = None)

A single segment within an AEM message: metadata plus a time-ordered sequence of attitude states.

Parameters:

Name Type Description Default
object_name str

Spacecraft name

required
object_id str

International designator

required
ref_frame_a str

Frame defining the transformation start point

required
ref_frame_b str

Frame defining the transformation end point

required
time_system str

Time system for all epochs in this segment

required
start_time Epoch

Start of the total time span covered by the data block

required
stop_time Epoch

End of the total time span covered by the data block

required
attitude_type str

Attitude representation for this segment's data, e.g. "QUATERNION", "QUATERNION/ANGVEL", "EULER_ANGLE", "SPIN"

required
center_name str | None

Celestial body the object is centered on (e.g. "EARTH")

None
useable_start_time Epoch | None

Start of the useable (interpolation-safe) span

None
useable_stop_time Epoch | None

End of the useable (interpolation-safe) span

None
euler_rot_seq EulerAngleOrder | None

Euler rotation sequence; required iff attitude_type is one of the Euler angle types

None
angvel_frame str | None

Frame in which angular velocity components are expressed; required iff attitude_type is one of the /ANGVEL types, and must equal ref_frame_a or ref_frame_b

None
interpolation_method str | None

Recommended interpolation method - "LINEAR", "HERMITE", or "LAGRANGE"

None
interpolation_degree int | None

Interpolation polynomial degree; required iff interpolation_method is present

None

Raises:

Type Description
ValueError

If time_system does not name a CCSDS time system.

BraheError

If attitude_type or interpolation_method does not name a value the CCSDS ADM defines.

Example
1
2
3
4
5
6
7
import brahe as bh
from brahe.ccsds import AEMSegment
t0 = bh.Epoch.from_datetime(2024, 1, 1, 0, 0, 0.0, 0.0, bh.TimeSystem.UTC)
t1 = t0 + 60.0
segment = AEMSegment(
    "SAT1", "2024-001A", "EME2000", "SC_BODY_1", "UTC", t0, t1, "QUATERNION"
)

Initialize instance.

angvel_frame property

angvel_frame: Any

str | None: Frame in which angular velocity components are expressed, or None unless attitude_type is one of the /ANGVEL types

attitude_type property

attitude_type: Any

str: Attitude representation and accompanying derivative/rate data for this segment

center_name property

center_name: Any

str | None: Celestial body the object is centered on

comments property

comments: Any

list[str]: Comments associated with the data block (before the first state)

euler_rot_seq property

euler_rot_seq: Any

EulerAngleOrder | None: Euler rotation sequence, or None unless attitude_type is one of the Euler angle types

interpolation_degree property

interpolation_degree: Any

int | None: Interpolation polynomial degree

interpolation_method property

interpolation_method: Any

str | None: Recommended interpolation method for this data block

metadata_comments property

metadata_comments: ndarray

list[str]: Metadata section comments

object_id property

object_id: Any

str: International designator

object_name property

object_name: Any

str: Spacecraft name

ref_frame_a property

ref_frame_a: Any

str: Frame defining the transformation start point

ref_frame_b property

ref_frame_b: Any

str: Frame defining the transformation end point

start_time property

start_time: Any

Epoch: Start of the total time span covered by the data block

states property

states: ndarray

list[AEMAttitudeState]: Time-ordered attitude states (owned copies)

stop_time property

stop_time: Any

Epoch: End of the total time span covered by the data block

time_system property

time_system: Any

str: Time system for all epochs in this segment

useable_start_time property

useable_start_time: Any

Epoch | None: Start of the useable (interpolation-safe) span

useable_stop_time property

useable_stop_time: Any

Epoch | None: End of the useable (interpolation-safe) span

add_state method descriptor

add_state(state: AEMAttitudeState) -> int

Append an attitude state to this segment.

Parameters:

Name Type Description Default
state AEMAttitudeState

Attitude state to append

required

Returns:

Name Type Description
int int

Index of the new state

Raises:

Type Description
BraheError

If the state's attitude type does not match the segment's attitude_type, or its epoch is not strictly after the last state's epoch


AEMAttitudeState

AEMAttitudeState()

A single AEM ephemeris line: an epoch plus attitude data at that epoch.

Construct with the static method matching the desired ATTITUDE_TYPE (from_quaternion, from_quaternion_derivative, from_quaternion_angvel, from_euler_angle, from_euler_angle_derivative, from_euler_angle_angvel, from_spin, from_spin_nutation, from_spin_nutation_mom). Unlike APMSpin, the spin constructors take no AngleFormat conversion: pass radian values directly.

Example
1
2
3
4
import brahe as bh
from brahe.ccsds import AEMAttitudeState
epoch = bh.Epoch.from_datetime(2024, 1, 1, 0, 0, 0.0, 0.0, bh.TimeSystem.UTC)
state = AEMAttitudeState.from_quaternion(epoch, bh.Quaternion(1.0, 0.0, 0.0, 0.0))

Initialize instance.

angular_velocity property

angular_velocity: Any

numpy.ndarray | None: Angular velocity vector [x, y, z] in rad/s, or None unless attitude_type is one of the /ANGVEL variants

attitude_type property

attitude_type: Any

str: ATTITUDE_TYPE token matching this state's variant (e.g. "QUATERNION", "QUATERNION/ANGVEL", "SPIN/NUTATION_MOM")

derivative property

derivative: Any

numpy.ndarray | None: Quaternion time derivative [q0_dot, q1_dot, q2_dot, q3_dot] (scalar-first), in 1/s, or None unless attitude_type is "QUATERNION/DERIVATIVE"

epoch property

epoch: Any

Epoch: Epoch of this attitude state

euler_angles property

euler_angles: float

EulerAngle | None: Euler angles (with rotation sequence), or None unless attitude_type is one of the EULER_ANGLE* variants

momentum_alpha property

momentum_alpha: Any

float | None: Right ascension of the angular momentum vector, in radians, or None unless attitude_type is "SPIN/NUTATION_MOM"

momentum_delta property

momentum_delta: Any

float | None: Declination of the angular momentum vector, in radians, or None unless attitude_type is "SPIN/NUTATION_MOM"

nutation property

nutation: Any

float | None: Nutation angle, in radians, or None unless attitude_type is "SPIN/NUTATION"

nutation_period property

nutation_period: Any

float | None: Nutation period, in seconds, or None unless attitude_type is "SPIN/NUTATION"

nutation_phase property

nutation_phase: Any

float | None: Inertial nutation phase, in radians, or None unless attitude_type is "SPIN/NUTATION"

nutation_vel property

nutation_vel: Any

float | None: Angular velocity of the spin axis around the momentum vector, in rad/s, or None unless attitude_type is "SPIN/NUTATION_MOM"

quaternion property

quaternion: Any

Quaternion | None: Attitude quaternion, or None unless attitude_type is one of the QUATERNION* variants

rates property

rates: Any

numpy.ndarray | None: Angle rates [angle_1_dot, angle_2_dot, angle_3_dot] in rad/s, in the same sequence order as euler_angles.order, or None unless attitude_type is "EULER_ANGLE/DERIVATIVE"

spin_alpha property

spin_alpha: Any

float | None: Right ascension of the spin axis in ref_frame_a, in radians, or None unless attitude_type is one of the SPIN* variants

spin_angle property

spin_angle: float

float | None: Phase angle about the spin axis, in radians, or None unless attitude_type is one of the SPIN* variants

spin_angle_vel property

spin_angle_vel: float

float | None: Angular velocity about the spin axis, in rad/s, or None unless attitude_type is one of the SPIN* variants

spin_delta property

spin_delta: Any

float | None: Declination of the spin axis in ref_frame_a, in radians, or None unless attitude_type is one of the SPIN* variants

from_euler_angle staticmethod

from_euler_angle(epoch: Epoch, angles: EulerAngle) -> AEMAttitudeState

Construct an EULER_ANGLE attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
angles EulerAngle

Euler angles (with rotation sequence) from ref_frame_a to ref_frame_b

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_euler_angle_angvel staticmethod

from_euler_angle_angvel(epoch: Epoch, angles: EulerAngle, angular_velocity: ndarray) -> AEMAttitudeState

Construct an EULER_ANGLE/ANGVEL attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
angles EulerAngle

Euler angles (with rotation sequence) from ref_frame_a to ref_frame_b

required
angular_velocity ndarray

Angular velocity vector [x, y, z], expressed in the segment's ANGVEL_FRAME. Units: rad/s

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_euler_angle_derivative staticmethod

from_euler_angle_derivative(epoch: Epoch, angles: EulerAngle, rates: ndarray) -> AEMAttitudeState

Construct an EULER_ANGLE/DERIVATIVE attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
angles EulerAngle

Euler angles (with rotation sequence) from ref_frame_a to ref_frame_b

required
rates ndarray

Angle rates [angle_1_dot, angle_2_dot, angle_3_dot], in the same sequence order as angles.order. Units: rad/s

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_quaternion staticmethod

from_quaternion(epoch: Epoch, quaternion: Quaternion) -> AEMAttitudeState

Construct a QUATERNION attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
quaternion Quaternion

Attitude quaternion from ref_frame_a to ref_frame_b

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_quaternion_angvel staticmethod

from_quaternion_angvel(epoch: Epoch, quaternion: Quaternion, angular_velocity: ndarray) -> AEMAttitudeState

Construct a QUATERNION/ANGVEL attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
quaternion Quaternion

Attitude quaternion from ref_frame_a to ref_frame_b

required
angular_velocity ndarray

Angular velocity vector [x, y, z], expressed in the segment's ANGVEL_FRAME. Units: rad/s

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_quaternion_derivative staticmethod

from_quaternion_derivative(epoch: Epoch, quaternion: Quaternion, derivative: ndarray) -> AEMAttitudeState

Construct a QUATERNION/DERIVATIVE attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
quaternion Quaternion

Attitude quaternion from ref_frame_a to ref_frame_b

required
derivative ndarray

Quaternion time derivative [q0_dot, q1_dot, q2_dot, q3_dot] (scalar-first), in 1/s

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_spin staticmethod

from_spin(epoch: Epoch, spin_alpha: float, spin_delta: float, spin_angle: float, spin_angle_vel: float) -> AEMAttitudeState

Construct a SPIN attitude state (simple, non-nutating spin).

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
spin_alpha float

Right ascension of the spin axis in ref_frame_a, in radians

required
spin_delta float

Declination of the spin axis in ref_frame_a, in radians

required
spin_angle float

Phase angle about the spin axis, in radians

required
spin_angle_vel float

Angular velocity about the spin axis, in rad/s

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_spin_nutation staticmethod

from_spin_nutation(epoch: Epoch, spin_alpha: float, spin_delta: float, spin_angle: float, spin_angle_vel: float, nutation: float, nutation_period: float, nutation_phase: float) -> AEMAttitudeState

Construct a SPIN/NUTATION attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
spin_alpha float

Right ascension of the spin axis in ref_frame_a, in radians

required
spin_delta float

Declination of the spin axis in ref_frame_a, in radians

required
spin_angle float

Phase angle about the spin axis, in radians

required
spin_angle_vel float

Angular velocity about the spin axis, in rad/s

required
nutation float

Nutation angle, in radians

required
nutation_period float

Nutation period, in seconds

required
nutation_phase float

Inertial nutation phase, in radians

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state

from_spin_nutation_mom staticmethod

from_spin_nutation_mom(epoch: Epoch, spin_alpha: float, spin_delta: float, spin_angle: float, spin_angle_vel: float, momentum_alpha: float, momentum_delta: float, nutation_vel: float) -> AEMAttitudeState

Construct a SPIN/NUTATION_MOM attitude state.

Parameters:

Name Type Description Default
epoch Epoch

Epoch of this attitude state

required
spin_alpha float

Right ascension of the spin axis in ref_frame_a, in radians

required
spin_delta float

Declination of the spin axis in ref_frame_a, in radians

required
spin_angle float

Phase angle about the spin axis, in radians

required
spin_angle_vel float

Angular velocity about the spin axis, in rad/s

required
momentum_alpha float

Right ascension of the angular momentum vector, in radians

required
momentum_delta float

Declination of the angular momentum vector, in radians

required
nutation_vel float

Angular velocity of the spin axis around the momentum vector, in rad/s

required

Returns:

Name Type Description
AEMAttitudeState AEMAttitudeState

New attitude state


See Also