astrix.spatial.frame module¶
- class Frame(rot, loc=None, ref_frame=None, backend=None, name='unnamed-frame')[source]¶
Bases:
objectA reference frame defined by a rotation and location. Can be static or time-varying, and can have rotation defined relative to another Frame. Combines RotationLike and Location objects, and manages time associations.
- Parameters:
rot (Rotation | RotationSequence) – A scipy Rotation object (single rotation) or RotationSequence (time-tagged rotations). If a single Rotation is provided, the frame rotation is static.
loc (Location, optional) – A Location object (Point or Path) defining the frame origin in ECEF coordinates. If not provided, the frame origin is assumed to be at the origin of the reference frame. If loc is provided, it must be a singular Point (1x3) for static frames. Use Path objects for time-varying locations.
ref_frame (Frame, optional) – A reference Frame object to define the rotation relative to. If not provided, the rotation is assumed to be absolute (e.g., from ECEF frame).
backend (BackendArg, optional) – Array backend to use (numpy, jax, etc.). Defaults to numpy.
name (str)
Examples
Static frame with static rotation and location:
>>> from astrix.primitives import Frame, Point >>> from scipy.spatial.transform import Rotation >>> >>> rot = Rotation.from_euler( ... "xyz", [90, 0, 0], degrees=True ... ) # 90 degree rotation about x-axis >>> loc = Point.from_geodet([27.47, 153.03, 0]) # Brisbane location >>> frame_static = Frame(rot, loc) # Frame with static rotation and location
>>> frame_static.interp_rot().as_euler("xyz", degrees=True) # Get absolute rotation array([[90., 0., 0.]]) >>> frame_static.loc.geodet # Get frame location in geodetic coordinates array([[153.03, 27.47, 0.0]])
Time-varying frame with rotation sequence and static location:
>>> from astrix.primitives import Time >>> from datetime import datetime, timezone >>> >>> times = Time.from_datetime( ... [ ... datetime(2021, 1, 1, 12, 0, 0, tzinfo=timezone.utc), ... datetime(2021, 1, 1, 13, 0, 0, tzinfo=timezone.utc), ... datetime(2021, 1, 1, 14, 0, 0, tzinfo=timezone.utc), ... ] ... ) >>> rots = Rotation.from_euler( ... "xyz", ... [ ... [0, 0, 0], ... [90, 0, 0], ... [180, 0, 0], ... ], ... degrees=True, ... ) >>> rot_seq = RotationSequence(rots, times) >>> loc = Point.from_geodet([27.47, 153.03, 0]) # Brisbane location >>> frame_dynamic_rot = Frame( ... rot_seq, loc ... ) # Frame with time-varying rotation and static location
>>> interp_rot = frame_dynamic_rot.interp_rot( ... Time.from_datetime(datetime(2021, 1, 1, 12, 30, 0, tzinfo=timezone.utc)) ... ) # Interpolate to halfway between first and second rotation >>> interp_rot.as_euler( ... "xyz", degrees=True ... ) # Get interpolated absolute rotation as Euler angles array([[45., 0., 0.]]) >>> frame_dynamic_rot.loc.geodet # Get frame location in geodetic coordinates array([[153.03, 27.47, 0.0]])
Frame defined relative to another frame:
>>> rot_ref = Rotation.from_euler( ... "xyz", [0, 30, 0], degrees=True ... ) # Reference frame >>> frame_ref = Frame(rot_ref, loc) # Reference frame >>> rot_rel = Rotation.from_euler("xyz", [0, 40, 0], degrees=True) >>> frame = Frame(rot_rel, ref_frame=frame_ref) >>> >>> frame.interp_rot().as_euler( ... "xyz", degrees=True ... ) # Absolute rotation (rot_ref * rot_rel) array([[ 0., 70., 0.]]) >>> frame.loc.geodet # (Same as reference frame) array([[153.03, 27.47, 0.0]])
Notes
If both loc and ref_frame are provided, the new frame location is used and the reference frame location is disregarded.
A TimeGroup object is created internally to manage time associations between rotation, location, and reference frame.
If the frame is static (single rotation and singular Point), the time properties return TIME_INVARIANT.
Use Path objects for time-varying locations.
- convert_to(backend)[source]¶
Convert the Frame object to a different backend.
- Return type:
- Parameters:
backend (str | Any | None)
- index_loc(index)[source]¶
Get the location of the frame at the given index.
Warning: This should only be used after downsampling so that location and rotation indeces align. Prefer interp_rot for general use.
- Return type:
- Parameters:
index (int)
- index_rot(index)[source]¶
Get the absolute rotation of the frame at the given index.
Warning: This should only be used after downsampling so that location and rotation indeces align. Prefer interp_rot for general use.
- Return type:
Rotation- Parameters:
index (int)
- interp_loc(time=TimeInvariant object, check_bounds=True)[source]¶
Get the interpolated location of the frame at the given times. If the location is static, time can be None.
- interp_rot(time=TimeInvariant object, check_bounds=True)[source]¶
Get the interpolated absolute rotation of the frame at the given times. If all rotations are time invariant, time can be None.
- Return type:
Rotation- Parameters:
time (TimeLike)
check_bounds (bool)
- replace_rot(frame_name, new_rot)[source]¶
Replace a rotation in the rotation chain with a new rotation.
This is an advanced feature and currently only applicable for static rotations. Should primarily be used for optimisation purposes in autograd frameworks.
- Parameters:
frame_name (str) – Name of the frame whose rotation is to be replaced.
new_rot (Rotation) – New scipy Rotation object to replace the existing rotation.
- Return type:
- sample_at_time(time)[source]¶
Sample the Frame object at specific times, returning a new Frame with time-varying components sampled at those times. The new frame can then be indexed at these times directly to avoid interpolation
- property backend: str¶
Get the name of the array backend in use (e.g., ‘numpy’, ‘jax’).
- property has_ref: bool¶
Check if the frame has a reference frame.
- property is_static: bool¶
Check if the frame is static (single rotation and singular Point location).
- property name: str¶
Get the name of the frame.
- property name_chain: list[str]¶
Get the names of all frames in the rotation chain, from base to current.
- property path: Path¶
Get the time-varying Path of the frame location, if applicable. If the frame location is static, raises AttributeError.
- property point: Point¶
Get the singular Point of the frame location, if applicable. If the frame location is time-varying, raises AttributeError.
- property rel_rot: RotationLike¶
Get the last rotation of the frame relative to the reference frame.
- heading_frame(path, downsample=1.0, name='heading frame')[source]¶
Create a heading-aligned frame at each point along a Path. The frame is defined such that the first aligns with the heading direction (azimuth), the z-axis aligns with the local vertical plane, and the y-axis completes the right-handed system.
- Parameters:
path (Path) – Path object defining the trajectory.
downsample (float, optional) – Downsample interval for Path objects in seconds. If None, no downsampling is performed. Defaults to 10s. If path time resolution is greater than downsample interval, the Path will be downsampled before creating the heading frame to reduce computational load.
name (str, optional) – Name of the frame. Defaults to “heading frame”.
- Returns:
Heading-aligned frame along the Path.
- Return type:
Notes
Adopts backend from Path object.
- ned_frame(loc, downsample=10.0, name='NED frame')[source]¶
Create a local NED (North-East-Down) frame at the given location(s). NED rotations are evaluated at all times in the Point/Path.
- Parameters:
loc (Location) – Location(s) to define the NED frame origin. Must be single point or time-varying Path.
downsample (float, optional) – Downsample interval for Path objects in seconds. If None, no downsampling is performed. Defaults to 10s. If loc is a Path and time resolution is greater than downsample interval, the Path will be downsampled before creating the NED frame to reduce computational load. Note that NED frames likely vary slowly compared to other frames (gimbals, aircraft, etc.), so downsampling is recommended for high-resolution paths.
name (str, optional) – Name of the frame. Defaults to “NED frame”.
- Returns:
NED frame at the given location(s).
- Return type:
Notes
Adopts backend from Location object.
- velocity_frame(path, downsample=1.0, name='velocity frame')[source]¶
Create a velocity-aligned frame at each point along a Path. The frame is defined such that the x-axis aligns with the velocity vector, the z-axis aligns with the local vertical plane, and the y-axis completes the right-handed system.
- Parameters:
path (Path) – Path object defining the trajectory.
downsample (float, optional) – Downsample interval for Path objects in seconds. If None, no downsampling is performed. Defaults to 10s. If path time resolution is greater than downsample interval, the Path will be downsampled before creating the velocity frame to reduce computational load.
name (str, optional) – Name of the frame. Defaults to “velocity frame”.
- Returns:
Velocity-aligned frame along the Path.
- Return type:
Notes
Adopts backend from Path object.