Skip to content

APM — Attitude Parameter Message

Parses CCSDS Attitude Parameter Messages containing a single-epoch attitude state through one or more logical blocks: quaternion, Euler angle, angular velocity, spin, inertia, and maneuver.


APM

APM(originator: Any, object_name: Any, object_id: Any, time_system: Any, epoch: Any, center_name: Any = None)

A CCSDS Attitude Parameter Message (APM).

APM messages describe a spacecraft's attitude at a single epoch through one or more logical blocks (quaternion, Euler angle, angular velocity, spin, inertia, maneuver). At least one logical block must be present for the message to be valid to write.

Can be created programmatically or parsed from KVN/XML/JSON.

Logical blocks are copied by value: apm.quaternion_states, apm.spins, etc. return independent copies of the underlying blocks, and add_quaternion_state/add_spin/etc. append a copy of the element passed in. Mutating a block returned from a list getter, or an element after it has been added, does not affect the parent APM.

Example
1
2
3
4
5
6
7
8
9
import brahe as bh
from brahe.ccsds import APM, APMQuaternionState

epoch = bh.Epoch.from_datetime(2024, 3, 1, 0, 0, 0.0, 0.0, bh.TimeSystem.UTC)
apm = APM("BRAHE", "SAT1", "2024-001A", "UTC", epoch, center_name="EARTH")
apm.add_quaternion_state(
    APMQuaternionState("ICRF", "SC_BODY_1", bh.Quaternion(1.0, 0.0, 0.0, 0.0))
)
print(apm.to_string("KVN"))

Initialize instance.

angular_velocities property

angular_velocities: Any

list[APMAngularVelocity]: Angular velocity blocks

center_name property

center_name: Any

str | None: Celestial body the object is centered on (e.g. "EARTH")

classification property

classification: Any

str | None: Classification marking

creation_date property

creation_date: Tuple[int, ...]

Epoch: Creation date of the message

epoch property

epoch: Any

Epoch: Epoch of the attitude elements and all blocks except maneuvers

euler_states property

euler_states: ndarray

list[APMEulerState]: Euler angle blocks

format_version property

format_version: Any

float: CCSDS format version

has_blocks property

has_blocks: bool

Whether at least one logical block is present.

Per CCSDS 504.0-B-2, a valid APM must contain at least one logical block.

Returns:

Name Type Description
bool bool

True if any logical block is present

inertias property

inertias: Any

list[APMInertia]: Inertia blocks

maneuvers property

maneuvers: Any

list[APMManeuver]: Maneuver blocks

message_id property

message_id: Any

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

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

originator property

originator: Any

str: Originator of the message

quaternion_states property

quaternion_states: ndarray

list[APMQuaternionState]: Attitude quaternion blocks

spins property

spins: Any

list[APMSpin]: Spin blocks

time_system property

time_system: Any

str: Time system used for the epoch and all epoch-valued keywords

add_angular_velocity method descriptor

add_angular_velocity(block: APMAngularVelocity) -> int

Add an angular velocity block.

Parameters:

Name Type Description Default
block APMAngularVelocity

Angular velocity block to append

required

Returns:

Name Type Description
int int

Index of the new block

add_euler_state method descriptor

add_euler_state(state: APMEulerState) -> int

Add a Euler angle block.

Parameters:

Name Type Description Default
state APMEulerState

Euler angle block to append

required

Returns:

Name Type Description
int int

Index of the new block

add_inertia method descriptor

add_inertia(inertia: APMInertia) -> int

Add an inertia block.

Parameters:

Name Type Description Default
inertia APMInertia

Inertia block to append

required

Returns:

Name Type Description
int int

Index of the new block

add_maneuver method descriptor

add_maneuver(man: APMManeuver) -> int

Add a maneuver block.

Parameters:

Name Type Description Default
man APMManeuver

Maneuver block to append

required

Returns:

Name Type Description
int int

Index of the new block

add_quaternion_state method descriptor

add_quaternion_state(state: APMQuaternionState) -> int

Add an attitude quaternion block.

Parameters:

Name Type Description Default
state APMQuaternionState

Quaternion block to append

required

Returns:

Name Type Description
int int

Index of the new block

add_spin method descriptor

add_spin(spin: APMSpin) -> int

Add a spin block.

Parameters:

Name Type Description Default
spin APMSpin

Spin block to append

required

Returns:

Name Type Description
int int

Index of the new block

from_file staticmethod

from_file(path: str) -> APM

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

Parameters:

Name Type Description Default
path str

Path to the APM file

required

Returns:

Name Type Description
APM APM

Parsed APM message

from_str staticmethod

from_str(content: str) -> APM

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

Parameters:

Name Type Description Default
content str

String content of the APM message

required

Returns:

Name Type Description
APM APM

Parsed APM message

to_dict method descriptor

to_dict() -> dict

Convert the APM 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 APM

to_file method descriptor

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

Write the APM 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 APM 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 APM 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 APM string


APMQuaternionState

APMQuaternionState(ref_frame_a: str, ref_frame_b: str, quaternion: Quaternion, quaternion_derivative: ndarray | None = None)

Attitude quaternion logical block of an APM.

Parameters:

Name Type Description Default
ref_frame_a str

Frame defining the transformation start point

required
ref_frame_b str

Frame defining the transformation end point

required
quaternion Quaternion

Attitude quaternion from ref_frame_a to ref_frame_b

required
quaternion_derivative ndarray | None

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

None
Example
1
2
3
import brahe as bh
from brahe.ccsds import APMQuaternionState
state = APMQuaternionState("ICRF", "SC_BODY_1", bh.Quaternion(1.0, 0.0, 0.0, 0.0))

Initialize instance.

comments property

comments: Any

list[str]: Comments

quaternion property

quaternion: Any

Quaternion: Attitude quaternion from ref_frame_a to ref_frame_b

quaternion_derivative property

quaternion_derivative: Any

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

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


APMEulerState

APMEulerState(ref_frame_a: str, ref_frame_b: str, angles: EulerAngle, rates: ndarray | None = None)

Euler angle logical block of an APM. The rotation sequence is carried by angles.order.

Parameters:

Name Type Description Default
ref_frame_a str

Frame defining the transformation start point

required
ref_frame_b str

Frame defining the transformation end point

required
angles EulerAngle

Euler angles (with rotation sequence) from ref_frame_a to ref_frame_b

required
rates ndarray | None

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

None
Example
1
2
3
4
import brahe as bh
from brahe.ccsds import APMEulerState
angles = bh.EulerAngle(bh.EulerAngleOrder.ZXZ, 10.0, 20.0, 30.0, bh.AngleFormat.DEGREES)
state = APMEulerState("ICRF", "SC_BODY_1", angles)

Initialize instance.

angles property

angles: float

EulerAngle: Euler angles (with rotation sequence) from ref_frame_a to ref_frame_b

comments property

comments: Any

list[str]: Comments

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 angles.order, or None

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


APMAngularVelocity

APMAngularVelocity(ref_frame_a: str, ref_frame_b: str, angvel_frame: str, angular_velocity: ndarray)

Angular velocity logical block of an APM.

Parameters:

Name Type Description Default
ref_frame_a str

Frame defining the transformation start point

required
ref_frame_b str

Frame defining the transformation end point

required
angvel_frame str

Frame in which angular_velocity components are expressed

required
angular_velocity ndarray

Angular velocity vector [x, y, z] in rad/s

required
Example
1
2
3
import numpy as np
from brahe.ccsds import APMAngularVelocity
block = APMAngularVelocity("ICRF", "SC_BODY_1", "SC_BODY_1", np.array([0.001, 0.0, 0.0]))

Initialize instance.

angular_velocity property

angular_velocity: Any

numpy.ndarray: Angular velocity vector [x, y, z] in rad/s

angvel_frame property

angvel_frame: Any

str: Frame in which angular_velocity components are expressed

comments property

comments: Any

list[str]: Comments

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


APMSpin

APMSpin(ref_frame_a: str, ref_frame_b: str, spin_alpha: float, spin_delta: float, spin_angle: float, spin_angle_vel: float, angle_format: AngleFormat)

Spin logical block of an APM. A spin block carries either the nutation angle triple, the nutation momentum triple, or neither (a simple, non-nutating spin) — see nutation_type.

Parameters:

Name Type Description Default
ref_frame_a str

Frame defining the transformation start point

required
ref_frame_b str

Frame defining the transformation end point

required
spin_alpha float

Right ascension of the spin axis in ref_frame_a

required
spin_delta float

Declination of the spin axis in ref_frame_a

required
spin_angle float

Phase angle about the spin axis

required
spin_angle_vel float

Angular velocity about the spin axis

required
angle_format AngleFormat

Units of spin_alpha, spin_delta, spin_angle, spin_angle_vel

required
Example
1
2
3
4
import brahe as bh
from brahe.ccsds import APMSpin
spin = APMSpin("ICRF", "SC_BODY_1", 10.0, 20.0, 30.0, 1.0, bh.AngleFormat.DEGREES)
spin.set_nutation_angle(5.0, 100.0, 15.0, bh.AngleFormat.DEGREES)

Initialize instance.

comments property

comments: Any

list[str]: Comments

momentum_alpha property

momentum_alpha: Any

float | None: Right ascension of the angular momentum vector in radians, or None unless nutation_type is "MOMENTUM"

momentum_delta property

momentum_delta: Any

float | None: Declination of the angular momentum vector in radians, or None unless nutation_type is "MOMENTUM"

nutation property

nutation: Any

float | None: Nutation angle in radians, or None unless nutation_type is "ANGLE"

nutation_period property

nutation_period: Any

float | None: Nutation period in seconds, or None unless nutation_type is "ANGLE"

nutation_phase property

nutation_phase: Any

float | None: Inertial nutation phase in radians, or None unless nutation_type is "ANGLE"

nutation_type property

nutation_type: Any

str: Nutation description variant - "NONE", "ANGLE", or "MOMENTUM"

nutation_vel property

nutation_vel: Any

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

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

spin_alpha property

spin_alpha: Any

float: Right ascension of the spin axis in ref_frame_a, in radians

spin_angle property

spin_angle: float

float: Phase angle about the spin axis, in radians

spin_angle_vel property

spin_angle_vel: float

float: Angular velocity about the spin axis, in rad/s

spin_delta property

spin_delta: Any

float: Declination of the spin axis in ref_frame_a, in radians

set_nutation_angle method descriptor

set_nutation_angle(nutation: float, nutation_period: float, nutation_phase: float, angle_format: AngleFormat) -> float

Set the nutation description to the NUTATION / NUTATION_PER / NUTATION_PHASE triple.

Parameters:

Name Type Description Default
nutation float

Nutation angle

required
nutation_period float

Nutation period, in seconds (unaffected by angle_format)

required
nutation_phase float

Inertial nutation phase

required
angle_format AngleFormat

Units of nutation and nutation_phase

required

set_nutation_momentum method descriptor

set_nutation_momentum(momentum_alpha: float, momentum_delta: float, nutation_vel: float, angle_format: AngleFormat) -> Any

Set the nutation description to the MOMENTUM_ALPHA / MOMENTUM_DELTA / NUTATION_VEL triple.

Parameters:

Name Type Description Default
momentum_alpha float

Right ascension of the angular momentum vector

required
momentum_delta float

Declination of the angular momentum vector

required
nutation_vel float

Angular velocity of the spin axis around the momentum vector

required
angle_format AngleFormat

Units of momentum_alpha, momentum_delta, and nutation_vel

required

APMInertia

APMInertia(inertia_ref_frame: str, ixx: float, iyy: float, izz: float, ixy: float, ixz: float, iyz: float)

Inertia logical block of an APM.

Parameters:

Name Type Description Default
inertia_ref_frame str

Reference frame the inertia tensor is expressed in

required
ixx float

Moment of inertia about X, in kg*m^2

required
iyy float

Moment of inertia about Y, in kg*m^2

required
izz float

Moment of inertia about Z, in kg*m^2

required
ixy float

Product of inertia XY, in kg*m^2

required
ixz float

Product of inertia XZ, in kg*m^2

required
iyz float

Product of inertia YZ, in kg*m^2

required
Example
from brahe.ccsds import APMInertia
inertia = APMInertia("SC_BODY_1", 6080.0, 5245.5, 8067.3, -135.9, 89.3, -90.7)

Initialize instance.

comments property

comments: Any

list[str]: Comments

inertia_matrix property

inertia_matrix: ndarray

numpy.ndarray: 3x3 symmetric inertia tensor, in kg*m^2. Per CCSDS 504.0-B-2 Annex F6, the cross-product (off-diagonal) terms are negated relative to the stored ixy/ixz/iyz fields.

inertia_ref_frame property

inertia_ref_frame: Any

str: Reference frame the inertia tensor is expressed in

ixx property

ixx: Any

float: Moment of inertia about X, in kg*m^2

ixy property

ixy: Any

float: Product of inertia XY, in kg*m^2

ixz property

ixz: Any

float: Product of inertia XZ, in kg*m^2

iyy property

iyy: Any

float: Moment of inertia about Y, in kg*m^2

iyz property

iyz: Any

float: Product of inertia YZ, in kg*m^2

izz property

izz: Any

float: Moment of inertia about Z, in kg*m^2


APMManeuver

APMManeuver(epoch_start: Epoch, duration: float, ref_frame: str, torque: ndarray, delta_mass: float | None = None)

Maneuver logical block of an APM. Unlike the other blocks, maneuvers are not relative to the message epoch.

Parameters:

Name Type Description Default
epoch_start Epoch

Epoch of maneuver start

required
duration float

Maneuver duration, in seconds

required
ref_frame str

Reference frame for the torque vector

required
torque ndarray

Torque vector [x, y, z], in N*m

required
delta_mass float | None

Mass change, in kg. Must be <= 0.

None

Raises:

Type Description
BraheError

If delta_mass is positive

Example
1
2
3
4
5
import numpy as np
import brahe as bh
from brahe.ccsds import APMManeuver
epoch = bh.Epoch.from_datetime(2024, 3, 1, 0, 0, 0.0, 0.0, bh.TimeSystem.UTC)
man = APMManeuver(epoch, 3.0, "ICRF", np.array([-1.25, -0.5, 0.5]))

Initialize instance.

comments property

comments: Any

list[str]: Comments

delta_mass property

delta_mass: Any

float | None: Mass change, in kg. Must be <= 0.

duration property

duration: Any

float: Maneuver duration, in seconds

epoch_start property

epoch_start: Any

Epoch: Epoch of maneuver start

ref_frame property

ref_frame: Any

str: Reference frame for the torque vector

torque property

torque: Any

numpy.ndarray: Torque vector [x, y, z], in N*m


See Also