Pure Nx implementation of the FABRIK algorithm.
Provides both position-only solving (fabrik/5) and full frame-based
solving with orientation (fabrik_with_orientation/7).
Summary
Functions
Run the FABRIK algorithm on a chain of points.
Run FABRIK with full orientation support.
Extract positions tensor from frames.
Convert points tensor to frames with identity orientations.
Types
@type frames() :: %{positions: Nx.Tensor.t(), orientations: Nx.Tensor.t()}
Frame representation for orientation-aware FABRIK.
:positions- Joint positions as{n+1, 3}tensor:orientations- Joint orientations as{n+1, 4}tensor (WXYZ quaternions)
Functions
@spec fabrik( points :: Nx.Tensor.t(), lengths :: Nx.Tensor.t(), target :: Nx.Tensor.t(), max_iterations :: pos_integer(), tolerance :: float() ) :: {:ok, Nx.Tensor.t(), map()} | {:error, :unreachable | :max_iterations, map()}
Run the FABRIK algorithm on a chain of points.
Parameters
points- Nx tensor of shape{n+1, 3}representing joint/link positionslengths- Nx tensor of shape{n}representing segment lengthstarget- Nx tensor of shape{3}representing target positionmax_iterations- Maximum number of iterationstolerance- Convergence tolerance (distance to target)
Returns
{:ok, new_points, meta}- Converged successfully{:error, :unreachable, meta}- Target is beyond reach{:error, :max_iterations, meta}- Did not converge within max iterations
In all cases, meta contains:
:points- Final point positions:iterations- Number of iterations performed:residual- Final distance to target
@spec fabrik_with_orientation( frames :: frames(), lengths :: Nx.Tensor.t(), target_position :: Nx.Tensor.t(), target_orientation :: BB.Math.Quaternion.t() | nil, max_iterations :: pos_integer(), tolerance :: float(), opts :: keyword() ) :: {:ok, frames(), map()} | {:error, :unreachable | :max_iterations, map()}
Run FABRIK with full orientation support.
Parameters
frames- Map with:positions{n+1, 3}and:orientations{n+1, 4}tensorslengths- Segment lengths as{n}tensortarget_position- Target position as{3}tensortarget_orientation- Target quaternion asQuaternion.t()ornilfor position-onlymax_iterations- Maximum solver iterationstolerance- Position convergence tolerance (metres)opts- Options including:orientation_tolerance(radians, default 0.01)
Returns
{:ok, frames, meta}- Converged successfully{:error, :unreachable, meta}- Target beyond reach{:error, :max_iterations, meta}- Did not converge
Meta includes:
:frames- Final frame state:iterations- Iterations performed:residual- Position residual (metres):orientation_residual- Orientation residual (radians) ornil
@spec frames_to_points(frames()) :: Nx.Tensor.t()
Extract positions tensor from frames.
@spec points_to_frames(Nx.Tensor.t()) :: frames()
Convert points tensor to frames with identity orientations.
Useful for using the orientation-aware algorithm with position-only data.