BB.Error.Kinematics.FABRIK.UnsupportedJoint exception (bb_ik_fabrik v0.8.0)

Copy Markdown View Source

The requested chain contains a joint FABRIK cannot solve for.

FABRIK is not Jacobian-based. It is a heuristic that iteratively repositions joints along a chain, treating each as a point connected by a fixed-length link, and a :planar or :floating joint has no meaningful interpretation in that scheme — there is no single point to reposition, and no fixed length between one and the next.

Refusing is better than approximating: a wrong answer from a solver that silently ignored three or six degrees of freedom looks exactly like a right one.

This is a property of the chain, not the robot

A legged robot whose body floats is a perfectly good FABRIK problem when each leg is solved from the body to the foot, because those chains contain nothing but revolute joints. Scope the solve past the multi-DoF joint with source_link and FABRIK handles it:

# The floating base is not part of this problem.
BB.IK.FABRIK.solve(robot, state, :body, :front_left_foot, target, [])

For a chain that genuinely must include the multi-DoF joint, use a Jacobian-based solver — bb_ik_dls is dimension-agnostic and needs no special case.

Summary

Types

t()

@type t() :: %BB.Error.Kinematics.FABRIK.UnsupportedJoint{
  __exception__: term(),
  bread_crumbs: term(),
  class: term(),
  joint: atom(),
  joint_type: :planar | :floating,
  path: term(),
  source_link: atom() | nil,
  splode: term(),
  stacktrace: term(),
  target_link: atom() | nil,
  vars: term()
}

Functions

exception(args)

@spec exception(opts :: Keyword.t()) :: %BB.Error.Kinematics.FABRIK.UnsupportedJoint{
  __exception__: term(),
  bread_crumbs: term(),
  class: term(),
  joint: term(),
  joint_type: term(),
  path: term(),
  source_link: term(),
  splode: term(),
  stacktrace: term(),
  target_link: term(),
  vars: term()
}

Create an Elixir.BB.Error.Kinematics.FABRIK.UnsupportedJoint without raising it.

Keys

  • :joint
  • :joint_type
  • :source_link
  • :target_link