BB.IK.FABRIK.Math (bb_ik_fabrik v0.3.2)

Copy Markdown View Source

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

Types

Frame representation for orientation-aware FABRIK.

Functions

Run the FABRIK algorithm on a chain of points.

Extract positions tensor from frames.

Convert points tensor to frames with identity orientations.

Types

frames()

@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

fabrik(points, lengths, target, max_iterations, tolerance)

@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 positions
  • lengths - Nx tensor of shape {n} representing segment lengths
  • target - Nx tensor of shape {3} representing target position
  • max_iterations - Maximum number of iterations
  • tolerance - 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

fabrik_with_orientation(frames, lengths, target_position, target_orientation, max_iterations, tolerance, opts \\ [])

@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} tensors
  • lengths - Segment lengths as {n} tensor
  • target_position - Target position as {3} tensor
  • target_orientation - Target quaternion as Quaternion.t() or nil for position-only
  • max_iterations - Maximum solver iterations
  • tolerance - 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) or nil

frames_to_points(frames)

@spec frames_to_points(frames()) :: Nx.Tensor.t()

Extract positions tensor from frames.

points_to_frames(points)

@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.