Forward kinematics expressed as a single composable defn.
BB.Robot.Kinematics packs a chain's static structure (joint origins, axes
and types) into plain tensors once, then calls fk_chain/6 to walk the chain
in one fused computation rather than dozens of eager per-op BB.Math calls.
Keeping the whole chain walk in defn is the point of beam-bots/bb#147: the
computation can be JIT-compiled and, with a leading batch axis on the inputs,
vectorised across many joint configurations or many targets at once.
Tensor layout
For a chain of n joints (root-most first), all inputs are :f64:
positions—{n}joint positions (radians for revolute, metres for prismatic)origin_rpy—{n, 3}per-joint origin orientation as{roll, pitch, yaw}origin_xyz—{n, 3}per-joint origin translationaxes—{n, 3}per-joint motion axis (unit vector)is_revolute—{n}1.0for revolute/continuous joints, else0.0is_prismatic—{n}1.0for prismatic joints, else0.0
The result is the {4, 4} base-to-tip homogeneous transform. The per-joint
transform reproduces BB.Math.Transform.from_origin/1 composed with the
motion transform: origin = Rx · Ry · Rz · T(xyz) and the motion is a
Rodrigues rotation about axis (revolute) or a translation along axis
(prismatic). Fixed/floating/planar joints carry both masks at 0.0, leaving
an identity motion.
Summary
Functions
Walk a kinematic chain, returning the {4, 4} base-to-tip transform.
Compute every link's base-frame transform via a topological prefix-product scan.
Orientation (angular-velocity) Jacobian of the chain tip.
Position Jacobian of the chain tip with respect to the chain joint positions.
Functions
Walk a kinematic chain, returning the {4, 4} base-to-tip transform.
See the module documentation for the tensor layout.
Compute every link's base-frame transform via a topological prefix-product scan.
One row per link, ordered root-first so a link's parent always precedes it
(parent_idx[i] < i for every non-root link). parent_idx indexes into this
same ordering; the root carries its own index and an identity joint transform,
so it resolves to the identity. The per-joint inputs follow the same layout as
fk_chain/6, describing each link's parent joint (identity-valued for the
root). Returns {n, 4, 4}, one transform per link in input order.
Orientation (angular-velocity) Jacobian of the chain tip.
Returns {3, n} where column j is the joint's rotation axis expressed in
the base frame (z_j) for revolute/continuous joints, and zero for prismatic
or fixed joints — the standard geometric angular Jacobian. Stacked beneath the
position Jacobian it forms the {6, n} spatial Jacobian, paired with a
base-frame rotation-vector orientation error.
Inputs follow the fk_chain/6 layout. A prefix-product scan walks the chain
accumulating the transform up to each joint's axis frame; grad is not
involved, so the data-dependent while is fine here.
Position Jacobian of the chain tip with respect to the chain joint positions.
Computed by differentiating fk_chain/6's tip translation via grad — the
composable-defn payoff #147 is after: no finite differences, no extra
forward-kinematics evaluations. Inputs follow the fk_chain/6 layout. Returns
{3, n}: row = spatial axis (x, y, z), column = chain joint in input order.