API
Reference Frames
Reference Frames module.
This module provides utilities for computing various reference frames used in the Perseo framework, including:
- Geocentric Reference Frame
- Geodetic Reference Frame
- ZeroDoppler Reference Frame
The main function compute_sensor_local_axis computes the local reference frame for a sensor based
on its position, velocity, and the specified reference frame type.
The module also includes functions for computing pointing directions from ARF and antenna angles
Attributes
ReferenceFrame
module-attribute
Functions:
compute_zerodoppler_reference_frame
compute_zerodoppler_reference_frame(sensor_positions: NDArray[floating], sensor_velocities: NDArray[floating]) -> npt.NDArray[np.floating]
Compute the axes of the ZeroDoppler reference frame.
Sensor positions and velocities are assumed to be expressed in ECEF coordinates.
Reference frame
- x-unit vector: oriented as sensor non-inertial velocity
- y-unit vector: given by the cross product between x and sensor position corrected with Earth eccentricity
- z-unit vector: completing the reference frame
Output frame has x as first column, y as second one and z as the last one. e.g. ux = zero_doppler_frame[..., 0], uy = zero_doppler_frame[..., 1], uz = zero_doppler_frame[..., 2]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor_positions
|
NDArray[floating]
|
sensor positions, with shape (3,) or (N, 3) |
required |
sensor_velocities
|
NDArray[floating]
|
sensor velocities, with shape (3,) or (N, 3) |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
zero doppler axes for each sensor position, with shape (3, 3) or (N, 3, 3) stored as columns of the output array. |
Raises:
| Type | Description |
|---|---|
ValueError
|
in case of invalid input |
compute_geocentric_reference_frame
compute_geocentric_reference_frame(sensor_positions: NDArray[floating], sensor_velocities: NDArray[floating]) -> npt.NDArray[np.floating]
Compute the axes of the geocentric reference frame.
Sensor positions and velocities are assumed to be expressed in ECEF coordinates.
Reference frame
- x-unit vector: completing the reference frame
- y-unit vector: given by the cross product between z and sensor inertial velocity
- z-unit vector: oriented as -sat_pos
Output frame has x as first column, y as second one and z as the last one. e.g. ux = geocentric_frame[..., 0], uy = geocentric_frame[..., 1], uz = geocentric_frame[..., 2]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor_positions
|
NDArray[floating]
|
sensor positions, with shape (3,) or (N, 3) |
required |
sensor_velocities
|
NDArray[floating]
|
sensor velocities, with shape (3,) or (N, 3) |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
geocentric reference frame for each sensor position, with shape (3, 3) or (N, 3, 3) stored as columns of the output array. |
compute_geodetic_reference_frame
compute_geodetic_reference_frame(sensor_positions: NDArray[floating], sensor_velocities: NDArray[floating]) -> npt.NDArray[np.floating]
Compute the axes of the geodetic reference frame.
Sensor positions and velocities are assumed to be expressed in ECEF coordinates.
Output frame has x as first column, y as second one and z as the last one. e.g. ux = geodetic_frame[..., 0], uy = geodetic_frame[..., 1], uz = geodetic_frame[..., 2]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor_positions
|
NDArray[floating]
|
sensor positions, with shape (3,) or (N, 3) |
required |
sensor_velocities
|
NDArray[floating]
|
sensor velocities, with shape (3,) or (N, 3) |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
geodetic reference frame for each sensor position, with shape (3, 3) or (N, 3, 3) stored as columns of the output array. |
compute_sensor_local_axis
compute_sensor_local_axis(sensor_positions: NDArray[floating], sensor_velocities: NDArray[floating], reference_frame: ReferenceFrame) -> npt.NDArray[np.floating]
Compute the axes of the sensor reference frame.
Sensor positions and velocities are assumed to be expressed in ECEF coordinates. Reference frame is one of "GEOCENTRIC", "GEODETIC", or "ZERODOPPLER".
Output frame has x as first column, y as second one and z as the last one. e.g. for "ZERODOPPLER" reference frame: ux = zero_doppler_frame[..., 0], uy = zero_doppler_frame[..., 1], uz = zero_doppler_frame[..., 2]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor_positions
|
NDArray[floating]
|
sensor positions, with shape (3,) or (N, 3) |
required |
sensor_velocities
|
NDArray[floating]
|
sensor velocities, with shape (3,) or (N, 3) |
required |
reference_frame
|
ReferenceFrame
|
reference frame, one of "GEOCENTRIC", "GEODETIC", or "ZERODOPPLER" |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
sensor local axis as a numpy array with shape (3, 3) or (N, 3, 3) |
Examples:
single position and velocity
>>> print(position.shape)
(3,)
>>> axis = compute_sensor_local_axis(position, velocity, "ZERODOPPLER")
>>> print(axis.shape)
(3, 3)
multiple position and velocity
compute_inertial_velocity
compute_inertial_velocity(sensor_positions: NDArray[floating], sensor_velocities: NDArray[floating]) -> npt.NDArray[np.floating]
Compute the sensor inertial velocity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor_positions
|
NDArray[floating]
|
sensor positions, with shape (3,) or (N, 3) |
required |
sensor_velocities
|
NDArray[floating]
|
sensor velocities, with shape (3,) or (N, 3) |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
inertial velocity, one for each sensor position, with shape (3,) or (N, 3) |
Raises:
| Type | Description |
|---|---|
ValueError
|
in case of invalid input |
compute_geodetic_point
Compute the geodetic point that corresponds to a sensor position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor_positions
|
NDArray[floating]
|
sensor positions, with shape (3,) or (N, 3) |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
geodetic points, with shape (3,) or (N, 3) |
Raises:
| Type | Description |
|---|---|
ValueError
|
sensor positions invalid shape |
Rotations
Rotation transformation utilities.
Attributes
RotationOrder
module-attribute
__all__
module-attribute
Functions:
euler_angles_to_rotation
Convert input Euler angles in radians to a SciPy Rotation object.
This is the reverse operation of
rotation_to_euler_angles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ypr_rad
|
NDArray[floating]
|
euler angles in radians with shape (3,) or (N, 3) with yaw, pitch, roll order. |
required |
order
|
('YPR', 'YRP', 'PRY', 'PYR', 'RYP', 'RPY')
|
order of application of the rotations corresponding to the provided euler angles. |
required |
Returns:
| Type | Description |
|---|---|
Rotation
|
a SciPy rotation object equivalent to the input euler angles matrix with the specified order |
Examples:
single rotation
>>> rotation = euler_angles_to_rotation(order="YPR", ypr_rad=[[0, 0, np.deg2rad(30.0)]])
>>> print(rotation.as_matrix())
[[ 1. 0. 0. ]
[ 0. 0.8660254 -0.5 ]
[ 0. 0.5 0.8660254]]
multiple rotation
>>> roll = np.deg2rad(np.arange(10, 26, 5, dtype=float))
>>> euler_angles = np.stack([np.zeros_like(roll), np.zeros_like(roll), roll], axis=-1)
>>> rotation = euler_angles_to_rotation(order="YPR", ypr_rad=euler_angles)
>>> print(rotation.as_matrix().shape)
(4, 3, 3)
rotation order as string
rotation_to_euler_angles
rotation_to_euler_angles(rotation: Rotation, order: RotationOrder) -> npt.NDArray[np.floating]
Compute euler angles array from the Rotation object and its rotation order.
This is the reverse operation of
euler_angles_to_rotation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation
|
Rotation
|
rotation matrix from which compute the euler angles |
required |
order
|
('YPR', 'YRP', 'PRY', 'PYR', 'RYP', 'RPY')
|
rotation order corresponding to the provided rotation |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
euler angles array, (N, 3) with yaw, pitch, roll order. |
Antenna Reference Frame
Antenna Reference Frame (ARF) module.
This module provides functions to compute the Antenna Reference Frame (ARF) from rotations and Euler angles, and to extract Euler angles from a given ARF.
Note
The Antenna Reference Frame (ARF) is a 3x3 matrix that represents the orientation of the antenna reference frame.
ARF Matrix Structure
Each column of the ARF matrix represents one axis of the antenna frame expressed in the local frame's coordinates:
Where:
- X_antenna: X-axis of the antenna frame (usually along-track direction)
- Y_antenna: Y-axis of the antenna frame (cross-track direction)
- Z_antenna: Z-axis of the antenna frame (boresight direction)
Accessing Antenna Reference Frame unit vectors
Individual axes (columns) can be accessed with:
X_antenna = arf[..., 0] # First column (X-axis)
Y_antenna = arf[..., 1] # Second column (Y-axis)
Z_antenna = arf[..., 2] # Third column (Z-axis)
Construction via Euler Angles
The ARF is typically constructed from three sequential rotations (Euler angles):
- Yaw (Z-axis rotation): Rotation around the local Z-axis
- Pitch (Y-axis rotation): Rotation around the local Y-axis
- Roll (X-axis rotation): Rotation around the local X-axis
These rotations are applied in certain order (usually YPR order (Yaw-Pitch-Roll)) to progressively rotate the initial reference frame into the antenna reference frame.
Vector Transformation
To rotate a vector v from the local frame to the antenna frame:
To rotate back from the antenna frame to the local frame (using transpose/inverse):
This is crucial for SAR processing where understanding antenna orientation relative to satellite motion and Earth's surface is essential.
Examples
Basic usage:
import numpy as np
from perseo_core.geometry.pointing import (
compute_antenna_reference_frame_from_euler_angles,
compute_sensor_local_axis,
)
# Define rotation angles
ypr_deg = np.array([5, 1, 30]) # yaw, pitch, roll in degrees
ypr_rad = np.deg2rad(ypr_deg)
# Sensor parameters in ECEF
sensor_positions = np.array([26512.279931507, 1064819.379506800, -7083173.555337110])
sensor_velocities = np.array([7529.609430015988, -342.978175622686, -23.376907795264])
# Compute local axis (ZERODOPPLER reference frame in ECEF)
local_axis = compute_sensor_local_axis(
sensor_positions=sensor_positions,
sensor_velocities=sensor_velocities,
reference_frame="ZERODOPPLER",
)
# Compute antenna reference frame (ARF) from Euler angles
arf = compute_antenna_reference_frame_from_euler_angles(
rotation_order="YPR",
ypr_rad=ypr_rad,
initial_reference_frame=local_axis,
)
# Access individual axes
print("Antenna Reference Frame:")
print(" X-axis:", arf[..., 0])
print(" Y-axis:", arf[..., 1])
print(" Z-axis (boresight):", arf[..., 2])
Attributes
__all__
module-attribute
__all__ = ['compute_antenna_reference_frame_from_euler_angles', 'compute_euler_angles_from_antenna_reference_frame', 'compute_pointing_directions']
Functions:
compute_antenna_reference_frame_from_rotation
compute_antenna_reference_frame_from_rotation(rotation: Rotation, initial_reference_frame: NDArray[floating] | None = None) -> npt.NDArray[np.floating]
Compute the Antenna Reference Frame (ARF) from a given rotation.
The ARF is obtained by rotating the initial reference frame with the given rotation. The rotation is assumed to be defined along the initial reference frame axes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation
|
Rotation
|
the rotation axes implicitely defined inside the rotation are the initial_reference_frame axes. |
required |
initial_reference_frame
|
NDArray[floating]
|
initial reference frame axes with shape (3, 3) or (N, 3, 3). If None, the initial reference frame is assumed to be the identity matrix. |
None
|
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
antenna reference frame axes as a numpy array with shape (3, 3) or (N, 3, 3) |
compute_rotation_from_antenna_reference_frame
compute_rotation_from_antenna_reference_frame(antenna_reference_frame: NDArray[floating], initial_reference_frame: NDArray[floating] | None = None) -> Rotation
Compute the rotation from a given Antenna Reference Frame (ARF).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
antenna_reference_frame
|
NDArray[floating]
|
antenna reference frame of the sensor, with shape (3, 3) or (N, 3, 3) |
required |
initial_reference_frame
|
NDArray[floating]
|
reference frame of the sensor, with shape (3, 3) or (N, 3, 3). If None, the initial reference frame is assumed to be the identity matrix. |
None
|
Returns:
| Type | Description |
|---|---|
Rotation
|
rotation from the initial reference frame to the antenna reference frame |
compute_antenna_reference_frame_from_euler_angles
compute_antenna_reference_frame_from_euler_angles(ypr_rad: NDArray[floating], rotation_order: RotationOrder, initial_reference_frame: NDArray[floating]) -> npt.NDArray[np.floating]
Compute the Antenna Reference Frame (ARF) from Euler angles (Yaw, Pitch and Roll).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ypr_rad
|
NDArray[floating]
|
euler angles in radians with shape (3,) or (N, 3) with yaw, pitch, roll order. |
required |
rotation_order
|
RotationOrder
|
order of applications of the rotations |
required |
initial_reference_frame
|
NDArray[floating]
|
reference frame of the sensor, with shape (3, 3) or (N, 3, 3) |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
antenna reference frame as a numpy array with shape (3, 3) or (N, 3, 3) |
compute_euler_angles_from_antenna_reference_frame
compute_euler_angles_from_antenna_reference_frame(antenna_reference_frame: NDArray[floating], initial_reference_frame: NDArray[floating], rotation_order: RotationOrder) -> npt.NDArray[np.floating]
Compute euler angles (Yaw, Pitch and Roll) from Antenna Reference Frame (ARF).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
antenna_reference_frame
|
NDArray[floating]
|
antenna reference frame of the sensor, with shape (3, 3) or (N, 3, 3) |
required |
initial_reference_frame
|
NDArray[floating]
|
reference frame of the sensor, with shape (3, 3) or (N, 3, 3) |
required |
rotation_order
|
RotationOrder
|
order of applications of the output euler angles |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
euler angles in radians with shape (3,) or (N, 3) with yaw, pitch, roll order. |
compute_pointing_directions
compute_pointing_directions(antenna_reference_frame: NDArray[floating], azimuth_antenna_angles: float | NDArray[floating], elevation_antenna_angles: float | NDArray[floating]) -> npt.NDArray[np.floating]
Compute the pointing directions corresponding to the given antenna angles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
antenna_reference_frame
|
NDArray[floating]
|
antenna reference frame for the sensor as a numpy array with shape (3, 3) or (N, 3, 3) |
required |
azimuth_antenna_angles
|
float | NDArray[floating]
|
scalar or (N,) array like, in radians |
required |
elevation_antenna_angles
|
float | NDArray[floating]
|
scalar or (N,) array like, in radians |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
pointing directions, with shape (3,) or (N, 3) |